【问题标题】:How to aggregate rows from a CSV, excluding ones based on a list of values如何聚合 CSV 中的行,排除基于值列表的行
【发布时间】:2022-11-17 14:20:56
【问题描述】:

我有一个包含以下数据的 csv:

"id","Title","Author(s)","Format","Size","Tags"
"1","Horse","John","KFX","122","Classic"
"1","Horse","John","KFX","122","Drama"
"1","Horse","John","KFX","122","Horror"
"1","Horse","John","AZW3","122","Classic"
"1","Horse","John","AZW3","122","Drama"
"1","Horse","John","AZW3","122","Horror"
"1","Horse","John","PDF","122","Classic"
"1","Horse","John","PDF","122","Drama"
"1","Horse","John","PDF","122","Horror"
"2","Banana","Anna","AZW3","312","SciFi"
"2","Banana","Julia","AZW3","312","SciFi"
"2","Banana","Anna","PDF","312","SciFi"
"2","Banana","Julia","PDF","312","SciFi"

我想,使用熊猫,得到这个:

"id","Title","Author(s)","Format","Size","Tags"
"1","Horse","John","KFX","122","Classic, Drama, Horror"
"2","Banana","Anna, Julia","AZW3","312","SciFi"

它将根据列表的值排除行的位置 KFX, AZW3, PDF

如果它有 KFX,则排除其他两个。 如果没有 KFX,请检查列表中的下一个 AZW3,如果存在,则排除 PDF(如果存在)

然后,汇总作者和标签。

我正在寻找这样做的方法,但到目前为止没有成功。 我试图按 id 分组,然后根据列表(KFX、AZW3、PDF)排除行,然后聚合。

我能够使用以下方法进行聚合:

df.groupby(['id']).agg(lambda x: ','.join(x))

但是有两个问题: 首先,它将包括包含所有“格式”的行。 其次,它也会重复其他列 “1、1、1”、“马、马、马”、“约翰、约翰、约翰”

等等。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用自定义函数来聚合:

    def uniq_str(l):
        return ', '.join(dict.fromkeys(map(str, l)))
    
    def agg_format(l):
        s = set(l) # not necessary if only 1 comparison
        if 'KFX' in s:
            return 'KFX'
        else:
            exclude = {'PDF'}
            return next((x for x in l if x not in exclude), None)
        
    df = pd.read_csv('file.csv')
        
    agg = {c: uniq_str for c in df}
    agg['Format'] = agg_format
    
    import csv 
    (df.groupby('id', as_index=False).agg(agg)
       .to_csv('out.csv', index=False, quoting=csv.QUOTE_ALL)
    )
    

    输出:

    "id","Title","Author(s)","Format","Size","Tags"
    "1","Horse","John","KFX","122","Classic, Drama, Horror"
    "2","Banana","Anna, Julia","AZW3","312","SciFi"
    

    【讨论】:

    • 惊人!!有用。太感谢了!我没有足够的编程经验,我花了一整天的时间来解决这个问题。
    【解决方案2】:
    def function1(dd:pd.DataFrame):
        lambda1=lambda x:dd.query("Format==@x").groupby('id,Title,Format,Size'.split(','),as_index=False).agg(set)
        
        if len(dd.query("Format=='KFX'"))>0:
            dd=lambda1('KFX')
        elif len(dd.query("Format=='AZW3'"))>0:
            dd=lambda1('AZW3')
        else:
            dd=lambda1('PDF')
        return dd.applymap(lambda x:','.join(x) if isinstance(x,set) else x)
    df1.groupby('id').apply(function1).set_index('id').rename_axis(None)
    
      Title Format  Size   Author(s)                  Tags
    1   Horse    KFX   122        John  Drama,Classic,Horror
    2  Banana   AZW3   312  Anna,Julia                 SciFi
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 2015-04-17
      相关资源
      最近更新 更多