
[英]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.