【问题标题】:DataFrame - Groupwise searching unique values - Is there a way to make this faster?DataFrame - Groupwise 搜索唯一值 - 有没有办法让它更快?
【发布时间】:2019-08-06 18:18:27
【问题描述】:

任务:
在列产品、天、pgroup、价格(逻辑键 = 产品、天)的数据框中,某些行列 pgroup 为空。如果该产品的其他数据集包含一个值,则应将其用于空数据集。

目前我正在遍历产品,为每个产品搜索组的唯一值。 我想以更快的方式做到这一点。

示例:

数据:

df = pd.DataFrame([['a','2018-02-03','G1',47],
              ['a','2018-02-04',None,25],
              ['a','2018-02-05','G1',10],
              ['a','2018-02-06',None,22],
              ['a','2018-02-07',None,84],
              ['b','2018-02-03',None,10],
              ['b','2018-02-04',None,21],
              ['b','2018-02-05',None,2],
              ['b','2018-02-06','G2',18],
              ['b','2018-02-07','G2',11],
              ['c','2018-02-03','G2',63],
              ['c','2018-02-04','G2',83],
              ['c','2018-02-05',None,20],
              ['c','2018-02-06',None,68],
              ['c','2018-02-07',None,33]])
df.columns = ['product','day','pgroup', 'value']

代码:

# Loop for each product
for xprod in df['product'].unique().tolist():
    # find unique values for pgroup
    unique_values = df[df['product'] == xprod]['pgroup'].unique()
    # Change Datatypes because of NaN-Values in Series
    unique_values_str = [str(i) for i in unique_values]
    # 2 values, first is NaN => take second 
    if len(unique_values_str) == 2 and (unique_values_str[0] == 'nan'):
        df.loc[df['product'] == xprod, 'pgroup'] = unique_values_str[1]
    # 2 values, second is NaN => take first
    elif len(unique_values_str) == 2 and (unique_values_str[1] == 'nan'):
        df.loc[df['product'] == xprod, 'pgroup'] = unique_values_str[0] 

预期结果:

    product     day         pgroup  value
0   a           2018-02-03  G1      47
1   a           2018-02-04  G1      25
2   a           2018-02-05  G1      10
3   a           2018-02-06  G1      22
4   a           2018-02-07  G1      84
5   b           2018-02-03  G2      10
6   b           2018-02-04  G2      21
7   b           2018-02-05  G2      2
8   b           2018-02-06  G2      18
9   b           2018-02-07  G2      11
10  c           2018-02-03  G2      63
11  c           2018-02-04  G2      83
12  c           2018-02-05  G2      20
13  c           2018-02-06  G2      68
14  c           2018-02-07  G2      33

注释:
根据我的检查,最耗时的部分是前两行:

 # Loop for each product
    for xprod in df['product'].unique().tolist():
        # find unique values for pgroup
        unique_values = df[df['product'] == xprod]['pgroup'].unique()

【问题讨论】:

  • 你的 MWE 坏了。 col_1 是什么?
  • 谢谢和抱歉。 col_1 应该是 pgroup。我改变了这个。

标签: python loops dataframe group-by


【解决方案1】:

这感觉有点老套,我真的不知道它会如何执行,但我认为它应该快一点。

df2 = df
df2['pgroup'] = df.groupby(['product'])['pgroup'].transform(lambda x : repr(set(x) - set([None]) ).replace("{'",'').replace("'}",'') )

如果它导致 pgroup 可以采用的值出现任何问题,您可能还必须更改它整理从 repr 生成的字符串的方式。

【讨论】:

  • 太棒了。就我而言,它将性能提高了 10-20 倍。注意:我必须将 None 替换为 pd.nan df2.groupby(['product'])['pgroup'].transform(lambda x : repr(set(x) - set([np.nan] )).replace("{'",'').replace("'}",''))
  • 我可以再问一个问题:为了获得更好的性能:是否可以将此逻辑限制为包含 NaN/ None 值的组?
  • 老实说我不确定,这可能值得另一个问题。我不会想到它会加快查询速度,即使你可以,因为你仍然需要对每个组执行操作以检查 nan 的存在,而唯一的实时增益是消除需要将组转换为不那么耗时的集合。
猜你喜欢
  • 2017-03-26
  • 2022-06-14
  • 1970-01-01
  • 2010-12-01
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多