質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

7872閲覧

pythonのpandasでのピボット風データ集約(サイズ大)について

uraco

総合スコア15

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

1クリップ

投稿2016/06/06 05:48

編集2016/06/06 22:46

レコード数が300万ぐらいのログデータがあります。
以下の集計したい項目のほかに、urlや時間などの項目もあります。。

id item
aaa 002
aaa 005
bbb 006
ccc 003

これをpandasのread_csvで読み込み、indexを「id」、columnsを「item」として、
データ数をカウントしたいと思っております。

下記2つの方法を試しましたが、うまくいきませんでした。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
・1通り目:pivotで集約
pivot_tableで集約しようとすると、次のようなエラーが出ます。

python

1df.pivot_table('url',index='id',columns='item',aggfunc='count')

「ValueError: negative dimensions are not allowed」

ネットで検索した結果、「サイズの大きく、かつ、スパースなndarrayを操作すると発生する」ようです。
なので、pivotでは集計が難しいでしょうか…?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
・2通り目:for文で地道に計算
下記のようなに集計しようとすると、PCがフリーズしてしまいます。

python

1df=pd.read_csv('logdata.csv') 2df1 = DataFrame(index=df['id'].unique(),columns=df['item'].unique()) 3for i in range(len(df['id'])): 4 df1.ix[df.iloc[i,0],df.iloc[i,1]]=1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

いずれの方法でも、データ量が1万程度なら問題なく動くことを確認しています。

1通り目に関してのpivotでのエラーの回避方法、もしくは別の方法などのお知恵をいただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lightson

2016/06/06 14:15

次の点を教えてもらえますか。 ・pivot_tableをどのように書いたか ・二つ目の方法のf2とはなんですか
uraco

2016/06/06 22:48 編集

pivot_tableは、他の使用していないnullのないカラムをカウント用に指定して集計しました。 二つ目のコードに間違いがあり、修正しました。失礼しました。。 よろしくお願いします!
guest

回答2

0

一千万個のダミーデータを作って動かしてみたところ、Macbook air 4Gで50秒程度で答えがでました。
実際のデータはどのようなものかはわかりませんが、集計に不必要なものを除いたデータフレームを作って試してみてはいかがでしょうか。

python

1import random 2import pandas as pd 3 4ids=['aaa','bbb','ccc','ddd','eee','fff'] 5items = ['001','002','003','004','005'] 6 7lst=[] 8for i in xrange(10000000): 9 lst.append([random.choice(ids),random.choice(items),i]) 10 11df = pd.DataFrame(lst) 12df.columns=['id','item','cnt'] 13df_cnt = df.pivot_table(values='cnt',index='id',columns='item',aggfunc='count') 14print df_cnt 15 16 17結果 18item 001 002 003 004 005 19id 20aaa 333172 332853 332715 332805 333969 21bbb 333405 332291 333239 333484 333567 22ccc 332545 333176 333521 333197 332859 23ddd 333978 333837 333153 333673 333523 24eee 332649 333473 332910 332809 334210 25fff 333865 332900 333881 334287 334054

投稿2016/06/07 13:32

lightson

総合スコア553

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uraco

2016/06/08 03:29 編集

ご回答ありがとうございます。 また、ダミーデータでのご確認もありがとうございます。参考になりました。 私の説明不足となり恐縮ですが、実際のデータは、idの数がユニークにすると47万件、itemの数は同様に19万件あります。。。 これが、「ValueError: negative dimensions are not allowed」というエラーになってしまう原因なのでしょうか・・・? もしそうなのであれば、pivotでの処理ではなく、他のコードでも結構です。 よい方法はありませんでしょうか?
lightson

2016/06/08 11:35

実際のデータがないのではっきりとは分かりませんが、IDやitemの数が多いせいではないと思います。エラーが「サイズの大きく、かつ、スパースなndarrayを操作すると発生する」が正しいなら、読み込んだデータからIDとitemだけのデータフレームを作り、それに対して処理を行えば、うまくいくのではないでしょうか。
uraco

2016/06/10 03:07

アドバイスありがとうございました。 必要な項目だけに絞って実行もしてみましたが、pivotにしようとすると、カウント「0」が多くなってしまうので、それがエラーの原因のような気がしています。 >読み込んだデータからIDとitemだけのデータフレームを作り、それに対して処理 こちらは質問に記載のようなfor文で地道にやりましたが、動きませんでした。。
guest

0

自己解決

今回は、pandasデータフレーム上での操作がうまくいかなかったので、フローを変え、csvデータから直接辞書型のデータを作成する方法で対処することにいたしました。

投稿2016/06/10 04:23

uraco

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問