我有一个相当大的CSV文件,它包含9917530行(不含页眉),54列。列是实数或整数,只有一列包含日期。文件中有一些NULL值,这些值被转换为 nan
当我把它加载到熊猫后 DataFrame
我喜欢这样。
import pandas as pd
data = pd.read_csv('data.csv')
加载后,我觉得非常快,因为它花了大约30秒(和用Unix工具数行的时间差不多)。wc
),这个过程占用了大约4Gb的内存(磁盘上的文件大小:2.2Gb.)。到目前为止一切正常。
然后我试着做了以下操作。
column_means = data.mean()
进程占用的内存很快就增加到了22Gb左右。我也可以看到处理器(一个核心)非常非常的忙碌--大概有三个小时,之后我就杀死了这个进程,因为我需要用这台机器做其他事情。我有一台速度相当快的Linux电脑--它有2个处理器,每个处理器有4个核心,所以总共有8个核心,还有32Gb的内存。我不相信计算列式需要这么长时间。
谁能解释一下原因?DataFrame.mean()
是如此之慢?更重要的是,有什么更好的方法来计算这样一个文件的列的手段?我是不是没有以最好的方式加载文件,我是否应该使用不同的函数来代替 DataFrame.mean()
或者是完全不同的工具?
非常感谢。
EDIT. 这里是什么 df.info()
显示。
<class 'pandas.core.frame.DataFrame'>
Int64Index: 9917530 entries, 0 to 9917529
Data columns (total 54 columns):
srch_id 9917530 non-null values
date_time 9917530 non-null values
site_id 9917530 non-null values
visitor_location_country_id 9917530 non-null values
visitor_hist_starrating 505297 non-null values
visitor_hist_adr_usd 507612 non-null values
prop_country_id 9917530 non-null values
prop_id 9917530 non-null values
prop_starrating 9917530 non-null values
prop_review_score 9902900 non-null values
prop_brand_bool 9917530 non-null values
prop_location_score1 9917530 non-null values
prop_location_score2 7739150 non-null values
prop_log_historical_price 9917530 non-null values
position 9917530 non-null values
price_usd 9917530 non-null values
promotion_flag 9917530 non-null values
srch_destination_id 9917530 non-null values
srch_length_of_stay 9917530 non-null values
srch_booking_window 9917530 non-null values
srch_adults_count 9917530 non-null values
srch_children_count 9917530 non-null values
srch_room_count 9917530 non-null values
srch_saturday_night_bool 9917530 non-null values
srch_query_affinity_score 635564 non-null values
orig_destination_distance 6701069 non-null values
random_bool 9917530 non-null values
comp1_rate 235806 non-null values
comp1_inv 254433 non-null values
comp1_rate_percent_diff 184907 non-null values
comp2_rate 4040633 non-null values
comp2_inv 4251538 non-null values
comp2_rate_percent_diff 1109847 non-null values
comp3_rate 3059273 non-null values
comp3_inv 3292221 non-null values
comp3_rate_percent_diff 944007 non-null values
comp4_rate 620099 non-null values
comp4_inv 692471 non-null values
comp4_rate_percent_diff 264213 non-null values
comp5_rate 4444294 non-null values
comp5_inv 4720833 non-null values
comp5_rate_percent_diff 1681006 non-null values
comp6_rate 482487 non-null values
comp6_inv 524145 non-null values
comp6_rate_percent_diff 193312 non-null values
comp7_rate 631077 non-null values
comp7_inv 713175 non-null values
comp7_rate_percent_diff 277838 non-null values
comp8_rate 3819043 non-null values
comp8_inv 3960388 non-null values
comp8_rate_percent_diff 1225707 non-null values
click_bool 9917530 non-null values
gross_bookings_usd 276592 non-null values
booking_bool 9917530 non-null values
dtypes: float64(34), int64(19), object(1)None
这里有一个类似大小的from ,但没有对象列。
In [10]: nrows = 10000000
In [11]: df = pd.concat([DataFrame(randn(int(nrows),34),columns=[ 'f%s' % i for i in range(34) ]),DataFrame(randint(0,10,size=int(nrows*19)).reshape(int(nrows),19),columns=[ 'i%s' % i for i in range(19) ])],axis=1)
In [12]: df.iloc[1000:10000,0:20] = np.nan
In [13]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000000 entries, 0 to 9999999
Data columns (total 53 columns):
f0 9991000 non-null values
f1 9991000 non-null values
f2 9991000 non-null values
f3 9991000 non-null values
f4 9991000 non-null values
f5 9991000 non-null values
f6 9991000 non-null values
f7 9991000 non-null values
f8 9991000 non-null values
f9 9991000 non-null values
f10 9991000 non-null values
f11 9991000 non-null values
f12 9991000 non-null values
f13 9991000 non-null values
f14 9991000 non-null values
f15 9991000 non-null values
f16 9991000 non-null values
f17 9991000 non-null values
f18 9991000 non-null values
f19 9991000 non-null values
f20 10000000 non-null values
f21 10000000 non-null values
f22 10000000 non-null values
f23 10000000 non-null values
f24 10000000 non-null values
f25 10000000 non-null values
f26 10000000 non-null values
f27 10000000 non-null values
f28 10000000 non-null values
f29 10000000 non-null values
f30 10000000 non-null values
f31 10000000 non-null values
f32 10000000 non-null values
f33 10000000 non-null values
i0 10000000 non-null values
i1 10000000 non-null values
i2 10000000 non-null values
i3 10000000 non-null values
i4 10000000 non-null values
i5 10000000 non-null values
i6 10000000 non-null values
i7 10000000 non-null values
i8 10000000 non-null values
i9 10000000 non-null values
i10 10000000 non-null values
i11 10000000 non-null values
i12 10000000 non-null values
i13 10000000 non-null values
i14 10000000 non-null values
i15 10000000 non-null values
i16 10000000 non-null values
i17 10000000 non-null values
i18 10000000 non-null values
dtypes: float64(34), int64(19)
时序(与您的机器规格相似)
In [14]: %timeit df.mean()
1 loops, best of 3: 21.5 s per loop
你可以通过预转换为浮点数来获得2倍的速度(mean也可以,但做的方式比较笼统,所以比较慢)
In [15]: %timeit df.astype('float64').mean()
1 loops, best of 3: 9.45 s per loop
你的问题是对象列。平均数会尝试计算所有的列,但由于对象列的原因,所有的列都被上报到了 object
dtype,计算效率不高。
最好的办法是做
df._get_numeric_data().mean()
有一个选项可以这样做 numeric_only
但由于某些原因,我们没有通过顶层函数(如平均值)直接支持这个参数。我认为会产生一个问题来添加这个参数。然而将可能是 False
(默认为不排除)。
你可以尝试一下这样的做法 -
pd.DataFrame(data.description())
我注意到这比我在数据框上使用平均数的情况下要快得多