我有很多要使用Pandas读取的csv文件(pd.read_csv),但是,在其中一些文件中途添加了一个没有标题的列,例如以下示例:>
Apples, Pears
1, 2
3, 4
5, 6, 7
如果使用pd.read_csv(example_file),则会引发以下错误“ ParserError:标记数据时出错。C错误:预期第4行中有2个字段,见3 ”
我想避免不必跳过这一行,而只是添加一个虚拟标题名称(如Unknown1),并得到以下结果:
Apples, Pears, Unknown1
1, 2, np.nan
3, 4, np.nan
5, 6, 7
答案 0 :(得分:4)
pandas
需要事先了解几何形状才能构建数据框。您可以阅读标题行并添加几个虚拟列名称以提供列数,然后重新读取整个csv并丢弃毕竟不使用的列。
>>> import pandas as pd
>>> names = list(pd.read_csv('foo.csv', nrows=0)) + ['unknown1', 'unknown2']
>>> df=pd.read_csv('foo.csv', names=names, skiprows=1).dropna(axis='columns', how='all')
>>> df
Apples Pears unknown1
0 1 2 NaN
1 3 4 NaN
2 5 6 7.0
如果有很多额外的列,并且您担心中间数据帧的内存占用,则可以使用csv
模块来扫描文件并计算最大行数。与pandas
不同,csv
非常高兴地发出大小可变的行。
>>> with open('foo.csv', newline='') as in_fp:
... reader = csv.reader(in_fp)
... header = next(reader)
... num_cols = max(len(row) for row in reader)
...
>>> names = header + ['unknown{}'.format(i+1) for i in range(num_cols-len(header))]
>>> df = pd.read_csv('foo.csv', names=names, skiprows=1)
>>> df
Apples Pears unknown1
0 1 2 NaN
1 3 4 NaN
2 5 6 7.0
答案 1 :(得分:1)
我们可以加载csv,然后在此之后解决您的问题
import io
t="""Apples, Pears
1, 2
3, 4
5, 6, 7"""
df = pd.read_csv(io.StringIO(t), sep='\t')
yourdf=df.iloc[:,0].str.split(', ',expand=True)
s=df.columns.str.split(', ').tolist()[0]
yourdf.columns=s+['unknow'+str(x+1) for x in range(yourdf.shape[1]-len(s))]
yourdf
Out[104]:
Apples Pears unknow1
0 1 2 None
1 3 4 None
2 5 6 7
答案 2 :(得分:0)
如果您事先不知道列数,则可以使用readlines()
预先确定所有行的最大列数,这是以失去已知标头名称为代价的。
sep = ',' # Define separator
lines = open("test.csv").readlines() # Open file and read lines
colcount = max([len(l.strip().split(sep)) for l in lines]) # Count separator
df = pd.read_csv("test.csv", names = range(colcount), skiprows = [0])
print df
0 1 2
0 1 2 NaN
1 3 4 NaN
2 5 6 7.0
到目前为止,colcount
还可应用于所有其他答案。
编辑:当心.csv以外的输入文件(请参见注释)