当前位置: 首页 > 知识库问答 >
问题:

根据条件替换和合并熊猫中的行

濮阳原
2023-03-14

我有一个数据框架:

   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个键的替换字典。使用简单的行明智提取和替换需要很长时间。

这(特别是最后一部分)如何有效地缩放?有人可以推荐熊猫的技巧吗?

共有3个答案

爱琪
2023-03-14

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)
融泓
2023-03-14

试试这个,我评论道

#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
东郭承业
2023-03-14

反转<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()

1map() 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列和

  • 我试图开发以下过滤器与熊猫数据帧: 我有四列,,,和 如何将其作为聚合函数编写? 下面是一个编写效率低下的工作示例: 输出:

  • 从该数据帧开始: 有一些缺失的值。我试图以行方式应用替换函数,例如在伪代码中: 我知道我可以做一些事情,比如: 函数定义如下: 获得: 但是先验地,我不知道字符串在列中的实际位置,所以我必须使用类似于的方法进行搜索,但要按行搜索。 编辑:每个字符串都可以出现在列中的任何位置。