从字典中转换数据类型时,在Pandas中使用read_csv

时间:2019-02-07 17:48:28

标签: python pandas

我正在将大型CSV读入数据框。熊猫将dtype设置为float64,这使用了大量内存(对于300MB CSV为2.4 GB),我想在导入期间将某些dtype设置为Int。我的数据集中有很多NaN,因此我尝试利用Pandas 0.24中的UInt dtype。

最初,我正在读取CSV,以仅提取包含源数据dtypes的标题和行#3。它的形式为U1,U2和F4,因此我使用df.replace将它们分别更改为熊猫dtypes,UInt8,UInt16和float64。然后,我从该数据帧创建字典。当我读取CSV时,我尝试使用该字典来定义dtype,但是我总是得到: 发生异常:TypeError 数据类型无法理解

import pandas as pd 
import numpy as np 

filename = r'input/TST_short.csv'
dtype_df = pd.read_csv(filename, nrows=1, skiprows=[1,2])

dtype_df.replace('U1', 'UInt8', inplace=True)
dtype_df.replace('U2', 'UInt16',inplace=True)
dtype_df.replace('F4', 'float64',inplace=True)

dtype_dict = dtype_df.to_dict('records')

df = pd.read_csv(filename, skiprows=range(1,5), nrows=500, dtype=dtype_dict)
print(df)

如果我删除dtype =参数,则df如下所示:

           TIME     ST1F  ST2F  ST3F  ST4F    P12V
0    43476.34869  32768.0   1.0   0.0   0.0  12.161
1    43476.34870      NaN   NaN   NaN   NaN     NaN
2    43476.34872      NaN   NaN   NaN   NaN     NaN
3    43476.34873      NaN   NaN   NaN   NaN     NaN
4    43476.34874      NaN   NaN   NaN   NaN     NaN
5    43476.34875      NaN   NaN   NaN   NaN     NaN
6    43476.34876      NaN   NaN   NaN   NaN     NaN
7    43476.34877      NaN   NaN   NaN   NaN     NaN
8    43476.34878      NaN   NaN   NaN   NaN     NaN
9    43476.34880      NaN   NaN   NaN   NaN     NaN
10   43476.34881  32768.0   1.0   0.0   0.0     NaN
11   43476.34882      NaN   NaN   NaN   NaN  12.161
12   43476.34883      NaN   NaN   NaN   NaN     NaN
13   43476.34884      NaN   NaN   NaN   NaN     NaN 

所有内容都转换为float64

字典(dtype_dict)如下:

{'TIME': 'float64', 'ST1F': 'UInt16', 'ST2F': 'UInt8', 'ST3F': 'UInt8', 'ST4F': 'UInt8', 'P12V': 'float64'}

如果我没有提供足够的信息,请放松一下,这是我的第一篇文章,我是新来的:)

更新:谢谢您的帮助,看来我的字典格式不正确。我已经尝试了所有字典类型,我以为记录是最近的,但是当我比较时可以看到我用方括号将字典从df包围起来。

d = dtype_df.to_dict('records')
d1 = {
    'TIME': 'float64',
    'ST1F': 'UInt16',
    'ST2F': 'UInt8',
    'ST3F': 'UInt8',
    'ST4F': 'UInt8',
    'P12V': 'float64'}

输出:

[{'TIME': 'float64', 'ST1F': 'UInt16', 'ST2F': 'UInt8', 'ST3F': 'UInt8', 'ST4F': 'UInt8', 'P12V': 'float64'}]
{'TIME': 'float64', 'ST1F': 'UInt16', 'ST2F': 'UInt8', 'ST3F': 'UInt8', 'ST4F': 'UInt8', 'P12V': 'float64'}

我正在生成字典的数据框的格式如下:

      TIME    ST1F   ST2F   ST3F   ST4F     P12V
0  float64  UInt16  UInt8  UInt8  UInt8  float64

2 个答案:

答案 0 :(得分:2)

您的代码完全按此处的预期运行。您确定使用的是0.24.0还是0.24.1?

In [27]: pd.read_csv('test.csv').head()  # Spits out floats
Out[27]:
          TIME     ST1F  ST2F  ST3F  ST4F    P12V
0  43476.34869  32768.0   1.0   0.0   0.0  12.161
1  43476.34870      NaN   NaN   NaN   NaN     NaN
2  43476.34872      NaN   NaN   NaN   NaN     NaN
3  43476.34873      NaN   NaN   NaN   NaN     NaN
4  43476.34874      NaN   NaN   NaN   NaN     NaN

In [28]: pd.read_csv('test.csv', dtype=d).head()  # Has the proper types
Out[28]:
          TIME   ST1F  ST2F  ST3F  ST4F    P12V
0  43476.34869  32768     1     0     0  12.161
1  43476.34870    NaN   NaN   NaN   NaN     NaN
2  43476.34872    NaN   NaN   NaN   NaN     NaN
3  43476.34873    NaN   NaN   NaN   NaN     NaN
4  43476.34874    NaN   NaN   NaN   NaN     NaN

In [29]: d  # Let's check that this dict matches yours on the nose
Out[29]:
{'TIME': 'float64',
 'ST1F': 'UInt16',
 'ST2F': 'UInt8',
 'ST3F': 'UInt8',
 'ST4F': 'UInt8',
 'P12V': 'float64'}

In [30]: pd.read_csv('test.csv', dtype=d).info()  # And the types look good as well
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 14 entries, 0 to 13
Data columns (total 6 columns):
TIME    14 non-null float64
ST1F    2 non-null UInt16
ST2F    2 non-null UInt8
ST3F    2 non-null UInt8
ST4F    2 non-null UInt8
P12V    2 non-null float64
dtypes: UInt16(1), UInt8(3), float64(2)
memory usage: 430.0 bytes

In [32]: pd.__version__
Out[32]: '0.24.0'

答案 1 :(得分:0)

问题是,我将字典作为包含字典的列表输出,可能有一种更优雅的方法来解决此问题,但我通过为包含字典的列表传递了index [0]来解决了这个问题。 / p>

df = pd.read_csv(filename, skiprows=range(1,5), dtype=d[0])

编辑:解决了这个问题,然后看到前面有答案的评论:)