2017-03-12 179 views
2

我正在阅读一个包含大约1000万行和20个不同列(带标题名称)的大型csv。大熊猫read_csv加速

我有值,2列与日期和一些字符串。

目前,它花了我大约150分钟,这样的加载数据:

df = pd.read_csv('data.csv', index_col='date', parse_dates = 'date') 

我想请问,我怎样才能使这个显著还快,具有相同的数据帧一次读取数据。

我尝试过使用HDF5数据库,但它一样慢。

子集我想读取数据的(我选择了8列,并给3行了实际20列和几百万行):

Date Comp  Rating Price Estprice Dividend? Date_earnings Returns 
3/12/2017 Apple Buy 100 114    Yes 4/4/2017 0.005646835 
3/12/2017 Blackberry Sell 120 97   No 4/25/2017 0.000775331 
3/12/2017 Microsoft Hold 140 100   Yes 5/28/2017 0.003028423 

谢谢你的建议。

+0

从HDF5读取数据应该快得多。你能提供一个样本数据集吗? – MaxU

+0

HDF5的问题,因为我有一个与大量的字符串,日期和数字df它没有快速运行(我使用'固定'的设置,并获得有关字符串表示的列的警告)。也许我错过了一个窍门。 – MysterioProgrammer91

+1

不解析这样的日期/你有一个不太标准的格式;然后解析然后用明确的格式在to_datetime – Jeff

回答

1

让我们测试一下!

数据生成:

sz = 10**3 

df = pd.DataFrame(np.random.randint(0, 10**6, (sz, 2)), columns=['i1','i2']) 
df['date'] = pd.date_range('2000-01-01', freq='1S', periods=len(df)) 
df['dt2'] = pd.date_range('1980-01-01', freq='999S', periods=len(df)) 
df['f1'] = np.random.rand(len(df)) 
df['f2'] = np.random.rand(len(df)) 
# generate 10 string columns 
for i in range(1, 11): 
    df['s{}'.format(i)] = pd.util.testing.rands_array(10, len(df)) 

df = pd.concat([df] * 10**3, ignore_index=True).sample(frac=1) 
df = df.set_index(df.pop('date').sort_values()) 

我们已经产生了以下DF

In [59]: df 
Out[59]: 
         i1  i2     dt2  f1  ...    s7   s8   s9   s10 
date                 ... 
2000-01-01 00:00:00 216625 4179 1980-01-04 04:35:24 0.679989  ...  7G8rLnoocA E7Ot7oPsJ6 puQamLn0I2 zxHrATQn0m 
2000-01-01 00:00:00 374740 967991 1980-01-09 11:07:48 0.202064  ...  wLETO2g8uL MhtzNLPXCH PW1uKxY0df wTakdCe6nK 
2000-01-01 00:00:00 152181 627451 1980-01-10 11:49:39 0.956117  ...  mXOsfUPqOy 6IIst7UFDT nL6XZxrT3r BxPCFNdZTK 
2000-01-01 00:00:00 915732 730737 1980-01-06 10:25:30 0.854145  ...  Crh94m085p M1tbrorxGT XWSKk3b8Pv M9FWQtPzaa 
2000-01-01 00:00:00 590262 248378 1980-01-06 11:48:45 0.307373  ...  wRnMPxeopd JF24uTUwJC 2CRrs9yB2N hxYrXFnT1H 
2000-01-01 00:00:00 161183 620876 1980-01-08 21:48:36 0.207536  ...  cyN0AExPO2 POaldI6Y0l TDc13rPdT0 xgoDOW8Y1L 
2000-01-01 00:00:00 589696 784856 1980-01-12 02:07:21 0.909340  ...  GIRAAVBRpj xwcnpwFohz wqcoTMjQ4S GTcIWXElo7 
...      ...  ...     ...  ...  ...    ...   ...   ...   ... 
2000-01-01 00:16:39 773606 205714 1980-01-12 07:40:21 0.895944  ...  HEkXfD7pku 1ogy12wBom OT3KmQRFGz Dp1cK5R4Gq 
2000-01-01 00:16:39 915732 730737 1980-01-06 10:25:30 0.854145  ...  Crh94m085p M1tbrorxGT XWSKk3b8Pv M9FWQtPzaa 
2000-01-01 00:16:39 990722 567886 1980-01-03 05:50:06 0.676511  ...  gVO3g0I97R yCqOhTVeEi imCCeQa0WG 9tslOJGWDJ 
2000-01-01 00:16:39 531778 438944 1980-01-04 20:07:48 0.190714  ...  rbLmkbnO5G ATm3BpWLC0 moLkyY2Msc 7A2UJERrBG 
2000-01-01 00:16:39 880791 245911 1980-01-02 15:57:36 0.014967  ...  bZuKNBvrEF K84u9HyAmG 4yy2bsUVNn WZQ5Vvl9zD 
2000-01-01 00:16:39 239866 425516 1980-01-10 05:26:42 0.667183  ...  6xukg6TVah VEUz4d92B8 zHDxty6U3d ItztnI5LmJ 
2000-01-01 00:16:39 338368 804695 1980-01-12 05:27:09 0.084818  ...  NM4fdjKBuW LXGUbLIuw9 SHdpnttX6q 4oXKMsaOJ5 

[1000000 rows x 15 columns] 

In [60]: df.shape 
Out[60]: (1000000, 15) 

In [61]: df.info() 
<class 'pandas.core.frame.DataFrame'> 
DatetimeIndex: 1000000 entries, 2000-01-01 00:00:00 to 2000-01-01 00:16:39 
Data columns (total 15 columns): 
i1  1000000 non-null int32 
i2  1000000 non-null int32 
dt2 1000000 non-null datetime64[ns] 
f1  1000000 non-null float64 
f2  1000000 non-null float64 
s1  1000000 non-null object 
s2  1000000 non-null object 
s3  1000000 non-null object 
s4  1000000 non-null object 
s5  1000000 non-null object 
s6  1000000 non-null object 
s7  1000000 non-null object 
s8  1000000 non-null object 
s9  1000000 non-null object 
s10 1000000 non-null object 
dtypes: datetime64[ns](1), float64(2), int32(2), object(10) 
memory usage: 114.4+ MB 

#print(df.shape) 
#print(df.info()) 

让我们把它写在不同格式的磁盘:(CSV,HDF5固定,HDF5表,羽):

# CSV 
df.to_csv('c:/tmp/test.csv') 
# HDF5 table format 
df.to_hdf('c:/tmp/test.h5', 'test', format='t') 
# HDF5 fixed format 
df.to_hdf('c:/tmp/test_fix.h5', 'test') 
# Feather format 
import feather 
feather.write_dataframe(df, 'c:/tmp/test.feather') 

时间:

现在我们可以从磁盘读取测量:

In [54]: # CSV 
    ...: %timeit pd.read_csv('c:/tmp/test.csv', parse_dates=['date', 'dt2'], index_col=0) 
1 loop, best of 3: 12.3 s per loop # 3rd place 

In [55]: # HDF5 fixed format 
    ...: %timeit pd.read_hdf('c:/tmp/test_fix.h5', 'test') 
1 loop, best of 3: 1.85 s per loop # 1st place 

In [56]: # HDF5 table format 
    ...: %timeit pd.read_hdf('c:/tmp/test.h5', 'test') 
1 loop, best of 3: 24.2 s per loop # 4th place 

In [57]: # Feather 
    ...: %timeit feather.read_dataframe('c:/tmp/test.feather') 
1 loop, best of 3: 3.21 s per loop # 2nd place 

如果你并不总是需要阅读所有数据,那么它将使意义存储在HDF5表格式的数据(并利用data_columns参数来索引那些将用于过滤的列)。

+0

将更新这个基准在文档:http://pandas.pydata.org/pandas-docs/stable/io。html#io-perf(更多格式和更多dtypes) - PR欢迎! – Jeff

+0

@Jeff,好的,我会试试看... – MaxU

0

根据您使用的数据,您可能会从read_csv中的“chunksize”参数中受益,其中you can find in the docs

如果您只需要对数据进行分析(您只需要加载数据一次),而您还没有使用像jupyter这样的IDE,那么一定要试试!当您尝试不同的操作时,您可以加载一次数据并将其保存在内存中。

我想你可能会在this thread找到任何其他建议。