将数据帧拆分为单独的CSV文件

时间:2017-09-08 21:20:25

标签: python pandas dataframe group-by pandas-groupby

我有一个相当大的csv,看起来像这样:

+---------+---------+
| Column1 | Column2 |
+---------+---------+
|       1 |   93644 |
|       2 |   63246 |
|       3 |   47790 |
|       3 |   39644 |
|       3 |   32585 |
|       1 |   19593 |
|       1 |   12707 |
|       2 |   53480 |
+---------+---------+

我的意图是

  1. 添加新列
  2. 在csv的每一行
  3. 中将特定值插入该列,' NewColumnValue'
  4. 根据Column1
  5. 中的值对文件进行排序
  6. 根据' Column1'的内容将原始CSV拆分为新文件,删除标题
  7. 例如,我希望最终得到多个文件,如下所示:

    +---+-------+----------------+
    | 1 | 19593 | NewColumnValue |
    | 1 | 93644 | NewColumnValue |
    | 1 | 12707 | NewColumnValue |
    +---+-------+----------------+
    
    +---+-------+-----------------+
    | 2 | 63246 | NewColumnValue |
    | 2 | 53480 | NewColumnValue |
    +---+-------+-----------------+
    
    +---+-------+-----------------+
    | 3 | 47790 | NewColumnValue |
    | 3 | 39644 | NewColumnValue |
    | 3 | 32585 | NewColumnValue |
    +---+-------+-----------------+
    

    我已设法使用单独的.py文件执行此操作:

    步骤1

    # -*- coding: utf-8 -*-
    import pandas as pd
    df = pd.read_csv('source.csv')
    df = df.sort_values('Column1')
    df['NewColumn'] = 'NewColumnValue'
    df.to_csv('ready.csv', index=False, header=False)
    

    第二步

    import csv
    from itertools import groupby
    for key, rows in groupby(csv.reader(open("ready.csv")),
                             lambda row: row[0]):
        with open("%s.csv" % key, "w") as output:
            for row in rows:
                output.write(",".join(row) + "\n")
    

    但我真的很想学习如何在单个.py文件中完成所有内容。我试过这个:

    # -*- coding: utf-8 -*-
    #This processes a large CSV file.  
    #It will dd a new column, populate the new column with a uniform piece of data for each row, sort the CSV, and remove headers
    #Then it will split the single large CSV into multiple CSVs based on the value in column 0 
    import pandas as pd
    import csv
    from itertools import groupby
    df = pd.read_csv('source.csv')
    df = df.sort_values('Column1')
    df['NewColumn'] = 'NewColumnValue'
    for key, rows in groupby(csv.reader((df)),
                             lambda row: row[0]):
        with open("%s.csv" % key, "w") as output:
            for row in rows:
                output.write(",".join(row) + "\n")
    

    但它不是按预期工作,而是为每个列标题指定了多个CSV。

    是否发生了这种情况,因为我在使用单独的.py文件时删除了标题行,而我在这里没有这样做?我不确定在拆分文件以删除标题时我需要做什么操作。

3 个答案:

答案 0 :(得分:6)

为什么不将groupby Column1分组并保存每个组?

df = df.sort_values('Column1').assign(NewColumn='NewColumnValue')
print(df)

   Column1  Column2       NewColumn
0        1    93644  NewColumnValue
5        1    19593  NewColumnValue
6        1    12707  NewColumnValue
1        2    63246  NewColumnValue
7        2    53480  NewColumnValue
2        3    47790  NewColumnValue
3        3    39644  NewColumnValue
4        3    32585  NewColumnValue
for i, g in df.groupby('Column1'):
    g.to_csv('{}.csv'.format(i), header=False, index_label=False)

感谢Unatiel improvementheader=False不会写标题,index_label=False也不会写索引列。

这会创建3个文件:

1.csv
2.csv
3.csv

每个人都拥有与每个Column1组相对应的数据。

答案 1 :(得分:0)

您不需要切换到itertools进行过滤,pandas具有内置的所有必要功能。

# -*- coding: utf-8 -*-
import pandas as pd
df = pd.read_csv('source.csv')
df = df.sort_values('Column1')  # Sorting isn't needed
df['NewColumn'] = 'NewColumnValue'
for key in df['Column1'].unique():  # For each value in Column1
    # These two steps can be combined into a single call
    # I'll separate for clarity:  
    # 1) filter the dataframe on the unique value
    dw = df[df['Column1']==key]   
    # 2) write the resulting dataframe without headers
    dw.to_csv("%s.csv" % key, header=False)  

答案 2 :(得分:0)

pandas.DataFrame支持将其数据写为csv to_csv()的方法。在这种情况下,您不需要csv模块。

import pandas as pd

df = pd.read_csv('source.csv')
df = df.sort_values('Column1').set_index('Column1')
df['NewColumn'] = 'NewColumnValue'
for key in df.index.unique():
    df.loc[key].to_csv('%d.csv' % int(key), header=False)

for key df.index.unique():将遍历索引中的每个唯一值。在您的示例中,它将循环遍历(1, 2 , 3)header=False将确保标题未写入输出文件。

要解释为什么在示例中出现错误输出,请尝试print(list(df))。这应输出df中的所有列。这就是for key, rows in csv.reader((df)):遍历df中的列的原因。

实际上,您应该为数据框中的每一列获得1 csv,其内容可能类似于,[NAME_OF_COLUMN],<itertools.... object at 0x.....>