Pandas read_csv读取包含空字符的列失败

7 投票
1 回答
3452 浏览
提问于 2025-04-17 13:27

下面的y列应该是['Reg', 'Reg', 'Swp', 'Swp']

In [1]: pd.read_csv('/tmp/test3.csv')  
Out[1]:  
x,y  
 ^@^@^@,Reg  
 ^@^@^@,Reg  
I,Swp  
I,Swp  

In [2]: ! cat /tmp/test3.csv  
     x    y  
0  
1  NaN  NaN  
2    I  Swp  
3    I  Swp    

In [3]: f = open('/tmp/test3.csv', 'rb'); print(repr(f.read()))  
'x,y\n \x00\x00\x00,Reg\n \x00\x00\x00,Reg\nI,Swp\nI,Swp\n'

1 个回答

6

是的,我能重现这个问题,但不知道怎么用 pd.read_csv 来解决。这里有个替代方法:

In [46]: import numpy as np
In [47]: arr = np.genfromtxt('test3.csv', delimiter = ',', 
                             dtype = None, names = True)

In [48]: df = pd.DataFrame(arr)

In [49]: df
Out[49]: 
   x    y
0     Reg
1     Reg
2  I  Swp
3  I  Swp

注意,当 names = True 时,CSV 文件的第一行有效数据会被当作列名(所以不会影响后面行的值的数据类型)。因此,如果 CSV 文件里有数字数据,比如:

In [22]: with open('/tmp/test.csv','r') as f:
   ....:     print(repr(f.read()))
   ....:     
'x,y,z\n \x00\x00\x00,Reg,1\n \x00\x00\x00,Reg,2\nI,Swp,3\nI,Swp,4\n'

那么 genfromtxt 会把第三列的类型设置为数字类型(在这个例子中是 <i4)。

In [19]: arr = np.genfromtxt('/tmp/test.csv', delimiter = ',', dtype = None, names = True)

In [20]: arr
Out[20]: 
array([('', 'Reg', 1), ('', 'Reg', 2), ('I', 'Swp', 3), ('I', 'Swp', 4)], 
      dtype=[('x', '|S3'), ('y', '|S3'), ('z', '<i4')])

不过,如果数字数据和字节数据混在一起,比如 '\x00',那么 genfromtxt 就无法把这一列识别为数字类型,而会把它当作字符串类型来处理。不过,你可以通过手动设置 dtype 参数来强制指定列的数据类型。例如:

In [11]: arr = np.genfromtxt('/tmp/test.csv', delimiter = ',', dtype = [('x', '|i4'), ('y', '|S3')], names = True)

这会把第一列 x 设置为 |i4(4字节整数),把第二列 y 设置为 |S3(3字节字符串)。想了解更多可用的数据类型,可以查看 这个文档页面

撰写回答