我有一个框架:
lft rel rgt num
0 t3 r3 z2 3
1 t1 r3 x1 9
2 x2 r3 t2 8
3 x4 r1 t2 4
4 t1 r1 z3 1
5 x1 r1 t2 2
6 x2 r2 t4 4
7 z3 r2 t4 5
8 t4 r3 x3 4
9 z1 r2 t3 4
字符串
还有一本参考字典:
replacement_dict = {
'X1' : ['x1', 'x2', 'x3', 'x4'],
'Y1' : ['y1', 'y2'],
'Z1' : ['z1', 'z2', 'z3']
}
型
我的目标是将所有出现的replacement_dict['X1']
替换为'X1',然后计算num
行的分组求和。
例如,'x1','x2','x3'或'x4'的任何示例将被'X1'等替换,并且'X1'-'r1'-'t2'组(由上面的重Map创建)的总数为6,等等。
所以我想要的输出是:
lft rel rgt num
0 X1 r3 t2 8
1 X1 r1 t2 6
2 X1 r2 t4 4
3 t1 r3 X1 9
4 t4 r3 X1 4
型
我正在使用一个有600万行的嵌套框架和一个有60,000个键的替换字典。这是永远使用一个简单的行明智的提取和替换。
如何有效地扩展这部分(特别是最后一部分)?有人可以推荐一个Pandas技巧吗?
6条答案
按热度按时间bfnvny8b1#
将
replacement_dict
Map和map()
这个新Map反向到lft和rgt列中的每一列,以替换某些值(例如x1->X1,y2->Y1等)。由于lft和rgt列中的某些值在Map中不存在(例如t1,t2等),因此调用fillna()
来填充这些值。1你也可以
stack()
需要替换的列(lft和rgt),调用map+fillna和unstack()
,但是因为只有2列,所以在这种情况下可能不值得这么麻烦。问题的第二部分可以通过在按lft、rel和rgt列分组后对num值求和来回答;所以
groupby().sum()
应该可以做到这一点。字符串
一曰:
map()
+fillna()
可能比replace()
更适合你的用例,因为在幕后,map()
实现了Cython优化的take_nd()
方法,如果有很多值需要替换,而replace()
实现的是使用Python循环的replace_list()
方法。(在您的情况下),性能差异将是巨大的,但如果replacement_dict
很小,replace()
可能会优于map()
。请参阅this answer,其中包括不同的基准测试,显示字典大小和字符串长度之间的相互作用,以了解何时使用
replace
以及何时使用map
+fillna
。u2nhd7ah2#
如果你翻转
replacement_dict
的键和值,事情会变得容易得多:字符串
xxslljrj3#
试试这个,我评论的步骤
字符串
输出量:
型
qlckcl4x4#
Pandas内置了 replace 函数,它比使用.loc遍历整个框架要快
你也可以在里面传递一个列表,使我们的字典很适合它
字符串
gg0vcinb5#
这里有一个方法来做你的问题问:
字符串
输出量:
型
说明:
replace()
使用字典的反向版本,将原始dict中列表中的项替换为相关df列lft
和rgt
中的相应键lft
或rgt
中具有'X1'
的行进行过滤后,使用groupby()
、sum()
和reset_index()
对num
列求和以获得唯一的lft, rel, rgt
组键,并将组组件从索引级别恢复到列。作为替代,我们可以使用
query()
只选择包含'X1'
的行:型
h22fl7wq6#
很多很棒的答案。我避免了对dict的需要,使用像这样的
df.apply()
来生成新数据。字符串
返回这个:
型