首页 > 解决方案 > 用熊猫读取具有可变列数的csv

问题描述

我有一个列数可变的 csv 文件。

Pandas 可以使用该参数相当轻松地处理这种情况name。如果文件的第一行长度相同或更短,则此方法有效names,但如果更长,则失败。

例子

情况1

第一行的元素数量与names

from io import StringIO
import pandas as pd

file = StringIO(
        '''1, 2, 3,
           1, 2
           1, 2, 3, 4, 
           1, 2, 3,''')

df = pd.read_csv(file, names=['A','B','C'], index_col=False)
df

# Out[0]:
#    A  B    C
# 0  1  2  3.0
# 1  1  2  NaN
# 2  1  2  3.0
# 3  1  2  3.0

行得通

案例2

第一行的元素少于names

from io import StringIO
import pandas as pd

file = StringIO(
        '''1, 2,
           1, 2
           1, 2, 3, 4, 
           1, 2, 3,''')

df = pd.read_csv(file, names=['A','B','C'], index_col=False)
df

# Out[0]:
#    A  B    C
# 0  1  2  NaN
# 1  1  2  NaN
# 2  1  2  3.0
# 3  1  2  3.0

这也有效

案例3

第一行的元素多于names

from io import StringIO
import pandas as pd

file = StringIO(
        '''1, 2, 3, 4,
           1, 2
           1, 2, 3, 4, 
           1, 2, 3,''')

df = pd.read_csv(file, names=['A','B','C'], index_col=False)
df

# Expected output:
#    A  B    C
# 0  1  2  3.0
# 1  1  2  NaN
# 2  1  2  3.0
# 3  1  2  3.0
#
# Instead I get:
# IndexError: list index out of range

不行!!!

问题

有没有办法让这个脚本更健壮,以便它也可以处理案例 3 而不会产生错误?这看起来是不是有点像bug

我正在运行熊猫版本 0.23.4

编辑:

案例 3b

第一行的元素多于names

from io import StringIO
import pandas as pd

file = StringIO(
        '''1, 2, 3, 4
           1, 2
           1, 2, 3, 4, 
           1, 2, 3,''') # NOTE: No comma after the first "4"!!

df = pd.read_csv(file, names=['A','B','C'], index_col=False)
df

#Out[0]:
#    A  B    C
# 0  1  2  3.0
# 1  1  2  NaN
# 2  1  2  3.0
# 3  1  2  3.0

行得通!!!

这到底是怎么回事?

标签: pythonpandas

解决方案


只需使用usecols参数,而不是那个namesnames假设您要列出所有列的名称,而usecols假设列的子样本。

from io import StringIO
import pandas as pd

file = StringIO(
        '''1, 2, 3, 4,
           1, 2
           1, 2, 3, 4, 
           1, 2, 3,''')

df = pd.read_csv(file, usecols =[0,1,2], header = None)
df
0   1   2
0   1   2   3.0
1   1   2   NaN
2   1   2   3.0
3   1   2   3.0

推荐阅读