以下是上一篇文章中的link。我在下面引用P.R.'s回复。
import pandas as pd
import glob
interesting_files = glob.glob("*.csv")
df_list = []
for filename in sorted(interesting_files):
df_list.append(pd.read_csv(filename))
full_df = pd.concat(df_list)
full_df.to_csv('output.csv')
我想知道如何使用pandas修改上述内容。具体来说,我试图以递归方式遍历目录并连接所有CSV标头及其各自的行值,然后将其写入一个文件中。使用P.R&#39的方法,导致所有标题及其相应的值彼此堆叠。我的约束是:
写出标题及其对应的值(没有"堆叠") - 基本上是一个接一个地连接
如果一个文件中的列标题与另一个文件匹配,那么它们应该不重复。只有在将值写入一个CSV文件时才应附加值。
由于每个文件都有不同的列标题和不同数量的列标题,因此应添加这些标题。什么都不应该删除。
我也尝试了以下内容:
import pandas as pd
import csv
import glob
import os
path = '.'
files_in_dir = [f for f in os.listdir(path) if f.endswith('csv')]
for filenames in files_in_dir:
df = pd.read_csv(filenames)
df.to_csv('out.csv', mode='a')
以下是两个示例CSV:
ID,Type,ACH,SH,LL,SS,LS,ISO,MID,Pass,TID,CID,TErrors
12821767,Query,,,,,,,,,,,
和
Type,ID,CC,CCD,Message,MemberIdentifier,NPass,UHB,UAP,NewAudioPIN,AType,ASuufix,Member,Share,Note,Flag,Card,MA,Preference,ETF,AutoT,RType,Locator,ISO,MID,Pass,TID,CID,Errors
UMember,12822909,True,10/31/2013 5:22:19 AM,,,,False,False,,,,,,,,,,,,,Member,,,,,,,
基于上述示例,输出应该是:
ID,Type,ACH,SH,LL,SS,LS,ISO,MID,Pass,TID,CID,TErrors,CC,CCD,Message,MemberIdentifier,NPass,UHB,UAP,NewAudioPIN,AType,ASuufix,Member,Share,Note,Flag,Card,MA,Preference,ETF,AutoT,RType,Locator,Errors
12822909,UMember,,,,,,,,,,,,True,10/31/2013 5:22:19 AM,,,,False,False,,,,,,,,,,,,,Member,,
12821767,Query ,,,,,,,,,,,,,,,,,,,,,,,,, etc.
(第二个样本中的所有标题列都应填入分隔符',对于第一行中没有相应标题的第二行,
如您所见,第二个样本有更多列标题。还有一些 标题是相同的(但顺序不同)。我想把所有的东西结合起来 这些 - 以及它们的价值观,符合上述要求。我是 想知道最好的方法是合并或执行可自定义的功能 大熊猫的内置方法?
答案 0 :(得分:1)
使用pandas
和OrderedDict
模块的非基于csv
的方法。
from glob import iglob
import csv
from collections import OrderedDict
files = sorted(iglob('*.csv'))
header = OrderedDict()
data = []
for filename in files:
with open(filename, 'rb') as fin:
csvin = csv.DictReader(fin)
try:
header.update(OrderedDict.fromkeys(csvin.fieldnames))
data.append(next(csvin))
except TypeError:
print filename, 'was empty'
except StopIteration:
print filename, "didn't contain a row"
with open('output_filename.csv', 'wb') as fout:
csvout = csv.DictWriter(fout, fieldnames=list(header))
csvout.writeheader()
csvout.writerows(data)
根据您的示例输入,这将为您提供:
ID,Type,ACH,SH,LL,SS,LS,ISO,MID,Pass,TID,CID,TErrors,CC,CCD,Message,MemberIdentifier,NPass,UHB,UAP,NewAudioPIN,AType,ASuufix,Member,Share,Note,Flag,Card,MA,Preference,ETF,AutoT,RType,Locator,Errors
12821767,Query,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
12822909,UMember,,,,,,,,,,,,True,10/31/2013 5:22:19 AM,,,,False,False,,,,,,,,,,,,,Member,,
答案 1 :(得分:-1)
在pandas中,您可以添加列名并轻松地重新排序数据框。请参阅this article on merging frames。
要附加框架并重新排序,您可以使用以下内容。重新索引就像使用列表一样简单。还有更多解决方案here。
import pandas,os
df = None
dfList=[]
for filename in [directory+x for x in os.listdir(path)]:
dfList.append(pd.read_csv(filename))
df=pandas.concat(dfList)
df.to_csv('out.csv', mode='w')
使用列表理解,这将是:
import pandas,os
pandas.concat([pd.read_csv(filename) for filename in [directory+x for x in os.listdir(path) if x.endswith("csv") is True]]).to_csv('out.csv', mode='w')
如果你想重新索引任何东西,只需使用一个清单。
cols=sorted(list(df.columns.values))
df=df[cols]
#or
df=df[sorted(list(df.columns.values))]