【问题标题】:How to create files from a groupby object, based on the length of the dataframe如何根据数据框的长度从 groupby 对象创建文件
【发布时间】:2021-04-28 19:32:48
【问题描述】:

我有一个如下所示的数据框 (df)(高度简化):

ID  A   B   C   VALUE
1   10  462 2241    217
2   11  498 6953    217
3   67  120 6926    654
4   68  898 7153    654
5   87  557 4996    654
6   88  227 6475    911
7   47  875 5097    911
8   48  143 8953    111
9   65  157 4470    111
10  66  525 9328    111

'VALUE' 列包含可变数量的具有相同值的行。我正在尝试输出一系列 csv 文件,其中包含所有包含 'VALUE' 长度 == 2、==3 等的行。例如:

to_csv('/Path/to/VALUE_len_2.csv')              
ID  A   B   C      VALUE
1   10  462 2241    217
2   11  498 6953    217
6   88  227 6475    911
7   47  875 5097    911
to_csv('/Path/to/VALUE_len_3.csv')              
ID  A   B   C      VALUE
3   67  120 6926    654
4   68  898 7153    654
5   87  557 4996    654
to_csv('/Path/to/VALUE_len_4.csv')              
ID  A   B   C      VALUE
7   47  875 5097    111
8   48  143 8953    111
9   65  157 4470    111
10  66  525 9328    111

我可以一次获得一个长度值的所需输出,例如,使用:

df = pd.concat(v for _, v in df.groupby("VALUE") if len(v) == 2)
df.to_csv("/Path/to/VALUE_len_2.csv")

但是,我有几十个值要测试。我想按以下顺序将其放入 for 循环中:

mylist = [2,3,4,5,6,7,8,9] or len([2,3,4,5,6,7,8,9])
grouped = df.groupby(['VALUE'])
output = '/Path/to/VALUE_len_{}.csv'

for loop here:
    if item in my list found in grouped:
        output rows to csv
    else:
        pass
  • 我尝试了各种构造来使用列表中的项目迭代 groupby 对象,但我无法使任何工作。
  • 尝试以这种方式使用 groupby 对象可能会出现问题,但很可能是我无法获得正确的语法来完成迭代。

【问题讨论】:

    标签: python pandas loops for-loop group-by


    【解决方案1】:
    • 使用预先确定的列表来创建文件名是没有意义的。
    • df_len 将用于使用f-string 生成文件名。
    • Path.exists()用于判断文件是否存在
    import pandas as pd
    from pathlib import Path
    
    # test data
    data = {'ID': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'A': [10, 11, 67, 68, 87, 88, 47, 48, 65, 66], 'B': [462, 498, 120, 898, 557, 227, 875, 143, 157, 525], 'C': [2241, 6953, 6926, 7153, 4996, 6475, 5097, 8953, 4470, 9328], 'VALUE': [217, 217, 654, 654, 654, 911, 911, 111, 111, 111]}
    df = pd.DataFrame(data)
    
    # groupby value
    for group, data in df.groupby('VALUE'):
        
        # get the length of the dataframe
        df_len = len(data)
        
        # create a filename with df_len
        file = Path(f'/path/to/VALUE_len_{df_len}.csv')
        
        # if the file exists, append without the header
        if file.exists():
            data.to_csv(file, index=False, mode='a', header=False)
            
        # create a new file
        else:
            data.to_csv(file, index=False) 
    

    • 如果您只能为特定长度的数据帧创建文件
    desired_length = [2, 3, 4, 5, 6, 7, 8, 9]
    
    # groupby value
    for group, data in df.groupby('VALUE'):
        
        # get the length of the dataframe
        df_len = len(data)
        
        # create a filename with df_len
        file = Path(f'/path/to/VALUE_len_{df_len}.csv')
        
        # check if the length of the dataframe is in the desired length
        if df_len in desired_length:
            
            # if the file exists, append without the header
            if file.exists():
                data.to_csv(file, index=False, mode='a', header=False)
    
            # create a new file
            else:
                data.to_csv(file, index=False)
    

    【讨论】:

    • 非常感谢!我在之前的尝试中看到了我的逻辑错误。我想创建一个特定长度的数据帧文件以节省处理时间和磁盘空间,因为在这 800,000+ 行数据集中可能有 3K 长度,我将定期只需要一个子集。我也很欣赏我的问题标题的编辑,使其更有意义。再次感谢。
    • @2kb 不客气。我很高兴这对你有用。
    【解决方案2】:
    # find the VALUE_len of every VALUE first
    df['VALUE_len'] = df.groupby('VALUE')['ID'].transform('count')
    cols = df.columns[:-1]
    # ['ID', 'A', 'B', 'C', 'VALUE']
    
    # save group by VALUE_len
    for VALUE_len, group in df.groupby('VALUE_len'):
        file = Path(f'/path/to/VALUE_len_{VALUE_len}.csv')
        group[cols].to_csv(file, index=False)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-28
      • 2021-12-09
      • 2016-05-14
      • 1970-01-01
      相关资源
      最近更新 更多