我有一个数据框架:
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']
}
我的目标是将所有出现的< code > replacement _ dict[' X1 ']替换为' X1 ',然后将这些行合并在一起。例如,“x1”、“x2”、“x3”或“x4”的任何实例都将被替换为“X1”等。
我可以通过选择包含任何这些字符串的行并将其替换为“X1”来实现这一点:
keys = replacement_dict.keys()
for key in keys:
DF.loc[DF['lft'].isin(replacement_dict[key]), 'lft'] = key
DF.loc[DF['rgt'].isin(replacement_dict[key]), 'rgt'] = key
给予:
lft rel rgt num
0 t3 r3 Z1 3
1 t1 r3 X1 9
2 X1 r3 t2 8
3 X1 r1 t2 4
4 t1 r1 Z1 1
5 X1 r1 t2 2
6 X1 r2 t4 4
7 Z1 r2 t4 5
8 t4 r3 X1 4
9 Z1 r2 t3 4
现在,如果我选择所有包含“X1”的行并将它们合并,我将得到:
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
因此,三列 ['lft', 'rel', 'rgt'] 是唯一的,而 “num” 列是这些行中的每一行相加的。上面的第 1 行 : ['X1' 'r1' 't2' 6] 是两行 ['X1' 'r1' 't2' 4] 和 ['X1' 'r1' 't2' 2] 的总和。
对于少量的行,我可以很容易地做到这一点,但是我正在使用具有600万行的数据框和具有60,000个键的替换字典。使用简单的行明智提取和替换需要很长时间。
这(特别是最后一部分)如何有效地缩放?有人可以推荐熊猫的技巧吗?
Pandas内置了函数替换,比使用. loc浏览整个数据框更快
您还可以在其中传递一个列表,使我们的字典非常适合它
keys = replacement_dict.keys()
# Loop through every value in our dictionary and get the replacements
for key in keys:
DF = DF.replace(to_replace=replacement_dict[key], value=key)
试试这个,我评论道
#reverse dict to dissolve the lists as values
reversed_dict = {v:k for k,val in replacement_dict.items() for v in val}
# replace the values
cols = ['lft', 'rel', 'rgt']
df[cols] = df[cols].replace(reversed_dict)
# filter rows where X1 is anywhere in the columns
df = df[df.eq('X1').any(axis=1)]
# sum the duplicate rows
out = df_filtered.groupby(cols).sum().reset_index()
print(out)
输出:
lft rel rgt num
0 X1 r1 t2 6
1 X1 r2 t4 4
2 X1 r3 t2 8
3 t1 r3 X1 9
4 t4 r3 X1 4
反转<code>replacement_dict</code>映射和<code>map()</code>此新映射到每个lft和rgt列,以替换某些值(例如x1-
您还可以将值需要替换的列(lft和rgt)堆叠()
),调用map fillna和unstack(),
但由于只有2列,因此对于这种特殊情况可能不值得麻烦。
问题的第二部分可以通过在按lft、rel和rgt列分组之后求和num值来回答;所以<code>groupby()。sum()应该能做到这一点。
# reverse replacement map
reverse_map = {v : k for k, li in replacement_dict.items() for v in li}
# substitute values in lft column using reverse_map
df['lft'] = df['lft'].map(reverse_map).fillna(df['lft'])
# substitute values in rgt column using reverse_map
df['rgt'] = df['rgt'].map(reverse_map).fillna(df['rgt'])
# sum values in num column by groups
result = df.groupby(['lft', 'rel', 'rgt'], as_index=False)['num'].sum()
1:map()
fillna()
可能比 replace()
更适合您的用例,因为在引擎盖下,map()
实现了一个 Cython 优化的 take_nd()
方法,如果有很多值要替换,则该方法的性能特别好,而 replace()
实现了使用 Python 循环replace_list()
方法。因此,如果replacement_dict
特别大(在你的情况下就是这样),性能的差异将是巨大的,但如果replacement_dict
很小,replace()
可能会优于map()。
我有一个数据帧(df),看起来像这样: 现在,我的目标是,对于列中的每个,应将列中关联的-值替换为字符串。 到目前为止我做了什么 我偶然发现了,它替换了每个(这不是我要找的),缺少值和,这似乎是我想要的,但不起作用。此外,我尝试了这个: 缺少索引或某种迭代器来访问列中的等效值 我试过这个: 这显然不起作用。 我看了几个问题,但不能基于答案中的建议。布莱克的问题西蒙的问题szli的问题扬·威廉斯·图
问题内容: 我有以下数据框 基本上我可以如下过滤行 我可以如下所示删除/删除一行 但是我想根据条件删除一定数量的行,我该怎么做? 问题答案: 最好的是但需要反转条件-使所有值相等且更高,如下所示: 与功能相同: 另一种可能的解决方案是通过以下方法反转掩码:
假设我有2个数据帧: DF1: Col1 | Col2 | Col3 XCN000370/17-18C|XCN0003711718C|0003971718 DF2 Col1 | Col2 | Col3 XCN0003711718C|XCN0003711718C|0003971718 我希望它们像这样合并: 首次匹配Col1(DF1)和Col1(DF2) 在保持不匹配的情况下,将Col1(DF1)与
我有一个熊猫数据框,大约有50列和
我试图开发以下过滤器与熊猫数据帧: 我有四列,,,和 如何将其作为聚合函数编写? 下面是一个编写效率低下的工作示例: 输出:
从该数据帧开始: 有一些缺失的值。我试图以行方式应用替换函数,例如在伪代码中: 我知道我可以做一些事情,比如: 函数定义如下: 获得: 但是先验地,我不知道字符串在列中的实际位置,所以我必须使用类似于的方法进行搜索,但要按行搜索。 编辑:每个字符串都可以出现在列中的任何位置。