8

かなり大きな CSV ファイルがあり、9917530 行 (ヘッダーなし) と 54 列が含まれています。列は実数または整数で、日付を含むのは 1 つだけです。ファイルにはいくつかの NULL 値があり、nanpandas にロードした後に変換されます。DataFrameこれは次のように行います。

import pandas as pd
data = pd.read_csv('data.csv')

ロード後、これは非常に高速だったと思いますが、約 30 秒かかりました (Unix ツールで行をカウントするのとほぼ同じ時間ですwc)。プロセスは約 4Gb の RAM (ディスク上のファイルのサイズ: 2.2) を使用していました。 Gb. これまでのところ、とても良いです。

次に、次のことを試みました。

column_means = data.mean()

プロセスが占有するメモリは、非常に急速に最大 22Gb まで増加しました。また、プロセッサ (1 つのコア) が非常にビジーであることがわかりました。その後 3 時間ほど、プロセスを強制終了しました。これは、マシンを他のことに使用する必要があったためです。私は Linux を搭載した非常に高速な PC を持っています。これには 2 つのプロセッサがあり、それぞれに 4 つのコアがあるため、全部で 8 つのコアと 32 Gb の RAM を搭載しています。列平均の計算にそれほど時間がかかるとは信じられません。

なぜDataFrame.mean()そんなに遅いのか誰か説明できますか?さらに重要なことに、そのようなファイルの列の平均を計算するより良い方法は何ですか? 可能な限り最善の方法でファイルをロードしませんでしたか?代わりに別の機能を使用するDataFrame.mean()か、まったく別のツールを使用する必要がありますか?

よろしくお願いします。

編集。ここに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
4

2 に答える 2

17

これは、同じサイズの 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

float に事前に変換することで 2 倍のスピードアップを得ることができます (つまり、これを行いますが、より一般的な方法で行うため、遅くなります)。

In [15]: %timeit df.astype('float64').mean()
1 loops, best of 3: 9.45 s per loop

問題はオブジェクト列です。Mean はすべての列を計算しようとしますが、オブジェクト列のためにすべてが dtype にアップキャストさobjectれ、計算には効率的ではありません。

最善の策はすることです

 df._get_numeric_data().mean()

numeric_only下位レベルでこれを行うオプションがありますが、何らかの理由でトップレベル関数 (平均など) を介してこれを直接サポートしていません。このパラメータを追加すると問題が発生すると思います。ただしFalse、デフォルトでは(除外しないように)可能性があります。

于 2013-09-09T16:02:21.830 に答える