[英]Pandas DataFrame: replace all values in a column, based on condition
[英]Replace values in pandas dataframe column with different replacement dict based on condition
我有一個數據框,我想在其中替換列中的值,但描述替換的字典基於另一列中的值。 示例數據框如下所示:
Map me strings date
0 1 test1 2020-01-01
1 2 test2 2020-02-10
2 3 test3 2020-01-01
3 4 test2 2020-03-15
我有一本看起來像這樣的字典:
map_dict = {'2020-01-01': {1: 4, 2: 3, 3: 1, 4: 2},
'2020-02-10': {1: 3, 2: 4, 3: 1, 4: 2},
'2020-03-15': {1: 3, 2: 2, 3: 1, 4: 4}}
我希望映射邏輯根據日期而不同。
在這個例子中,預期的輸出是:
Map me strings date
0 4 test1 2020-01-01
1 4 test2 2020-02-10
2 1 test3 2020-01-01
3 4 test2 2020-03-15
我有一個龐大的數據幀(100M+ 行),所以我真的想盡可能避免任何循環解決方案。
我試圖想辦法使用 map 或 replace 但沒有成功
將DataFrame.join
與由DataFrame
和DataFrame.stack
創建的MultiIndex Series
DataFrame.stack
:
df = df.join(pd.DataFrame(map_dict).stack().rename('new'), on=['Map me','date'])
print (df)
Map me strings date new
0 1 test1 2020-01-01 4
1 2 test2 2020-02-10 4
2 3 test3 2020-01-01 1
3 4 test2 2020-03-15 4
也許嘗試這樣的事情?
df['mapped'] = df.apply(lambda x: map_dict[x['date']][x['Map me']], axis=1)
嘗試使用np.where ,它通常比熊貓具有更好的性能:
df["Mapped"] = ""
for key in map_dict.keys():
df["Mapped"] = np.where((df["date"] == key)&(df["Mapped"] == ""), df["Map me"].apply(lambda x: map_dict[key][x]), df["Mapped"])
結果:
Map me strings date Mapped
0 1 test1 2020-01-01 4
1 2 test2 2020-02-10 4
2 3 test3 2020-01-01 1
3 4 test2 2020-03-15 4
一種更像熊貓的方法是將map_dict
轉換為DataFrame
並將其加入您的示例框架。 例如:
# Create the original dataframe
>>> df = pd.DataFrame([(1, 'test1', '2020-01-01'), (2, 'test2', '2020-02-10'), (3, 'test3', '2020-01-01'), (4, 'test2', '2020-03-15')], columns=['Map me', 'strings', 'date'])
>>> df
Map me strings date
0 1 test1 2020-01-01
1 2 test2 2020-02-10
2 3 test3 2020-01-01
3 4 test2 2020-03-15
# Convert the map dict to a dataframe
>>> map_df = pd.DataFrame([(k, j, l) for k, v in map_dict.items() for j,l in v.items()], columns=['date', 'Map me', 'Map to'])
>>> map_df
date Map me Map to
0 2020-01-01 1 4
1 2020-01-01 2 3
2 2020-01-01 3 1
3 2020-01-01 4 2
4 2020-02-10 1 3
5 2020-02-10 2 4
6 2020-02-10 3 1
7 2020-02-10 4 2
8 2020-03-15 1 3
9 2020-03-15 2 2
10 2020-03-15 3 1
11 2020-03-15 4 4
# Perform the join
>>> mapped_df = pd.merge(df, map_df, left_on=['date', 'Map me'], right_on=['date', 'Map me'])
>>> mapped_df
Map me strings date Map to
0 1 test1 2020-01-01 4
1 2 test2 2020-02-10 4
2 3 test3 2020-01-01 1
3 4 test2 2020-03-15 4
>>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.