【问题标题】:Python: Split CSV file according to first character of the first columnPython:根据第一列的第一个字符拆分CSV文件
【发布时间】:2016-11-24 14:52:34
【问题描述】:

我有一系列大型 CSV 文件“basename.csv”,例如:

B1,3,5,6

B2,2,1,5

B3,1,9,0

C1,4,7,9

C2,1,9,3

C3,8,5,2

我想将它们拆分成不同的文件,例如:

basename_B.csv

B1,3,5,6

B2,2,1,5

B3,1,9,0

basename_C.csv

C1,4,7,9

C2,1,9,3

C3,8,5,2

我过去已经用 for 循环和 ifs 做过类似的事情,但我想知道是否有更有效的方法可以用 Pandas 或其他方法来做这件事。

解决方案

从@chthonicdaemon 和@jezrael 改编解决方案,我想出了这个:

def split_csv():
    for dfile in glob.glob('*.csv'):
        df = pd.read_csv(dfile, header=None)
        for letter, group in df.groupby(df[0].str[0]):
            group.to_csv((os.path.splitext(dfile)[0]) + '_{}.csv'.format(letter), index=False, header=False)

split_csv()

【问题讨论】:

  • 您可以使用df.ix[:,df.columns.str.startswith('B')] 来过滤列
  • 是的,谢谢,问题是我不知道每个文件中有哪些字母。我当然可以创建一个独特字母列表并循环它,但我想知道是否有更优雅的解决方案。此外,您的解决方案还抓取第一个以外的列。

标签: python csv pandas split multiple-columns


【解决方案1】:

这是groupby的简单应用:

df = pandas.read_csv('basename.csv', header=None)

def firstletter(index):
    firstentry = df.ix[index, 0]
    return firstentry[0]

for letter, group in df.groupby(firstletter):
    group.to_csv('basename_{}.csv'.format(letter))

或者,结合@jezrael 通过列的显式内容进行分组:

for letter, group in df.groupby(df[0].str[0]):
    group.to_csv('basename_{}.csv'.format(letter))

【讨论】:

  • 感谢一百万!虽然这两种提议的解决方案都有效,但它更简单、更优雅。
  • 有问题,等一下。
  • The rough rule is any time you see back-to-back square brackets, ][, you're in asking for trouble.tomaugspurger.github.io/modern-1.html
  • @jezrael 我认为这不适用于这里,因为第二个索引实际上是获取字符串的第一个元素。所以 pandas 部分以df.ix[x, 0] 结束。不过,我会改写它以使其更具可读性。
【解决方案2】:

我认为您可以通过第一级索引创建MultiIndex 然后groupby 并使用to_csv

import pandas as pd
from pandas.compat import StringIO

temp=u"""B1,3,5,6
B2,2,1,5
B3,1,9,0
C1,4,7,9
C2,1,9,3
C3,8,5,2"""
#after testing replace StringIO(temp) to filename
df = pd.read_csv(StringIO(temp), header=None)
print (df)
    0  1  2  3
0  B1  3  5  6
1  B2  2  1  5
2  B3  1  9  0
3  C1  4  7  9
4  C2  1  9  3
5  C3  8  5  2

另一个类似的解决方案作为另一个答案:

for letter, g in df.groupby([df.iloc[:, 0].str[0]]):
    #print (letter)
    #print (g)
    g.to_csv('basename_{}.csv'.format(letter))

【讨论】:

  • 对不起,我认为最初的问题并不清楚。我已经对其进行了编辑以将其作为示例。
  • 我总是忘记.str。很好的收获。
  • 我经常忘记dropna() ;) 美好的一天!
【解决方案3】:

我测试了这段代码,应该可以满足您的要求。 example.csv 将是 csv 输入文件。

with open ('example.csv') as f:
    r = f.readlines()

for i in range(len(r)):
    row = r[i]
    letter = r[i].split(',')[0][0]
    filename = "basename_"+letter.upper()+".csv"
    with open(filename,'a') as f:
        f.write(row)

【讨论】:

  • 这个解决方案的好处是它纯粹是pythonic,不需要Pandas。谢谢!
猜你喜欢
  • 2021-06-25
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2016-09-09
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多