2017-07-14 5 views
1

を繰り返し単語を数えることができます:あなたが見ればは、どのように私はget_dummiesを使用して文字列カラムを使用して2つのデータフレームに参加し、私は以下の例持つややマトリックスビューを作成しようとしていますこんにちは、文字列の中

import pandas as pd 
sales = [{'account': 'Jones,LLC', 'Jan': 150}, 
      {'account': 'Alpha,Co', 'Jan': 200}, 
      {'account': 'Blue,Inc', 'Jan': 50,}] 
df = pd.DataFrame(sales) 
sales2 = [{'account': 'Jones,LLC,Co,Jones'}, 
     {'account': 'Alpha,Co,Blue'}, 
     {'account': 'Blue,Inc',}] 
df2 = pd.DataFrame(sales2) 

df3=df.join(df2.account.str.get_dummies(sep=',')) 
df3.head() 

をdf2を見ると、最初の行にJonesという文字列が2回含まれていることがわかります。df3を見ると、Jones列の最初の行が1で、df2の最初の行に2回表示されます。

私は

|---------------------|------------------| 
|  account  | Jones   | 
|---------------------|------------------| 
|  Jones,LLC  |   1  | 
|---------------------|------------------ 

私はこれを取得したい(私だけが興味のあるDFの割合を示す)これを取得するには:

|---------------------|------------------| 
|  account  | Jones   | 
|---------------------|------------------| 
|  Jones,LLC  |   2  | 
|---------------------|------------------ 

答えて

2

私はSeries.str.get_dummiesを信じていない使用することを想定していますこの方法では、各変数のバイナリ・インジケータ(カウントではなく)を返します。 pd.get_dummiesdocumentationには、この現象を示すいくつかの例があります。あなたが示すように、これは正確に結合することができる

from collections import Counter 
df2.account.str.split(',').apply(lambda x: pd.Series(Counter(x))) 
# Alpha Blue Co Inc Jones LLC 
# 0 NaN NaN 1.0 NaN 2.0 1.0 
# 1 1.0 1.0 1.0 NaN NaN NaN 
# 2 NaN 1.0 NaN 1.0 NaN NaN 
# add .fillna(0) to the end of the expression of you don't want NaN values 

:各部分の数を取得する別の解決策があるかもしれません

が、それを行うには1つの簡単な方法は、collectionsモジュールからCounterである

df.join(df2.account.str.split(',').apply(lambda x: pd.Series(Counter(x)))) 
# Jan account Alpha Blue Co Inc Jones LLC 
# 0 150 Jones,LLC NaN NaN 1.0 NaN 2.0 1.0 
# 1 200 Alpha,Co 1.0 1.0 1.0 NaN NaN NaN 
# 2 50 Blue,Inc NaN 1.0 NaN 1.0 NaN NaN 
+1

これは良い答えです!一を足す。私は 'apply'の後に' fillna(0).astype(int) 'を追加したいと思います。 – piRSquared

+0

ありがとうございました! –

2

オプション1
pd.value_counts

df.join(df2.account.str.split(',').apply(pd.value_counts).fillna(0).astype(int)) 

    Jan account Alpha Blue Co Inc Jones LLC 
0 150 Jones,LLC  0  0 1 0  2 1 
1 200 Alpha,Co  1  1 1 0  0 0 
2 50 Blue,Inc  0  1 0 1  0 0 

オプション2
np.bincount
これはpd.factorizenp.bincountの組み合わせを使用して、はるかに関与し、透明性がより低い、方法です。早く!しかし明らかではない。これはまた、pandas 'apiを評価する動機付けとしても機能します。

rows = split(df2.account.values.astype(str), ',') 
lens = [len(row) for row in rows.tolist()] 
vals = np.concatenate(rows) 
f, u = pd.factorize(vals) 
n, m = len(lens), u.size 
i = np.arange(n).repeat(lens) 
counts = np.bincount(i * m + f, minlength=n * m).reshape(n, m) 

df.join(pd.DataFrame(counts, df2.index, u)) 

    Jan account Jones LLC Co Alpha Blue Inc 
0 150 Jones,LLC  2 1 1  0  0 0 
1 200 Alpha,Co  0 0 1  1  1 0 
2 50 Blue,Inc  0 0 0  0  1 1 

タイミング

%%timeit 
rows = split(df2.account.values.astype(str), ',') 
lens = [len(row) for row in rows.tolist()] 
vals = np.concatenate(rows) 
f, u = pd.factorize(vals) 
n, m = len(lens), u.size 
i = np.arange(n).repeat(lens) 
counts = np.bincount(i * m + f, minlength=n * m).reshape(n, m) 

df.join(pd.DataFrame(counts, df2.index, u)) 

1000 loops, best of 3: 685 µs per loop 

%timeit df.join(df2.account.str.split(',').apply(pd.value_counts).fillna(0).astype(int)) 

100 loops, best of 3: 2.34 ms per loop 

%timeit df.join(df2.account.str.split(',').apply(lambda x: pd.Series(Counter(x))).fillna(0).astype(int)) 

1000 loops, best of 3: 1.74 ms per loop 
関連する問題