【问题标题】:Filtering and grouping rows in one DataFrame, by another DataFrame通过另一个 DataFrame 过滤和分组一个 DataFrame 中的行
【发布时间】:2020-10-28 05:31:59
【问题描述】:

我有两个 DF。我想遍历 DF1 中的行并过滤 DF2 中具有相同 id 的所有行,并在 DF1 的新列中获取列“B”值。

data = {'id': [1,2,3]}
df1 = pd.DataFrame(data)

data = {'id': [1, 1, 3,3,3], 'B': ['ab', 'bc','ad','ds','sd']}
df2 = pd.DataFrame(data)

DF1 - id(15k 行) DF2 - id, col1(50M 行)

期望的输出

data = {'id': [1,2,3],'B':['[ab,bc]','[]','[ad,ds,sd]']}
pd.DataFrame(data)

def func(df1):
    temp3=df2.merge(pd.DataFrame(data=[df1.values]*len(df1),columns=df1.index),how='right',on= 
    ['id'])
    temp1 = temp3.B.values
    return temp1
df1['B']=df1.apply(func,axis=1))

我在 df1 上使用合并来过滤和应用 lambda 函数。该代码在大型数据帧上执行需要 1 小时。如何让它运行得更快?

【问题讨论】:

  • id=2 在输出的列表中有一个额外的项目,不确定这是否有意义。
  • df1df2 具有相同的 ID。这是巧合吗?如果没有,你为什么需要df1?如果是,您能否向任一数据帧添加一些其他 ID?
  • @cs95:编辑了输出。
  • 另外,你真的想要列表外观的 strings 作为输出吗?
  • @DYZ:编辑了输出。我不需要字符串作为输出。只是所有具有 id 的关联 B 列值的数组

标签: python pandas dataframe optimization


【解决方案1】:

您是否在寻找简单的过滤器和分组列表?

df2[df2['id'].isin(df1['id'])].groupby('id', as_index=False)[['B']].agg(list)

   id             B
0   1      [ab, bc]
1   2      [ca, as]
2   3  [ad, ds, sd]

请注意,按列表分组在性能方面被认为是次优的。

【讨论】:

  • 当你说次优时你在比较它是什么?字符串?
  • 这是一个很好的解决方案。我希望它在 50M 行时运行得非常快。虽然,来自 df1 的所有 id 都不会在 df2 中。所以,也许我需要在这一步之后创建一个额外的合并。
  • @Datanovice 与可矢量化的 dtypes(本质上不是字符串或对象的任何东西)相比。
  • @krishnaagrawal 我的代码中的 [df2['id'].isin(df1['id'])] 步骤说明了这一点,并预先过滤掉了不匹配的 ID,还是我弄错了?
  • 此输出将仅包含两个 df 中常见的 id。所以,我将这个结果与 df​​1 合并,并用 '[]' 替换空值以获得完整列表。 df1 = df1.merge(result,how='left', on=['id']) df1.loc[df['B'].isnull(),['B']] = df1.loc[df1[ 'B'].isnull(),'B'].apply(lambda x: [])
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 2023-02-09
  • 1970-01-01
  • 2016-05-25
  • 2021-11-10
相关资源
最近更新 更多