パンダデータフレームの行を反復して新しい列を作成する


10

私はこのようなパンダデータフレーム(X11)を持っています:実際には私は99列までdx99まで持っています

    dx1      dx2    dx3    dx4
0   25041   40391   5856    0
1   25041   40391   25081   5856
2   25041   40391   42822   0
3   25061   40391   0       0
4   25041   40391   0       5856
5   40391   25002   5856    3569

25041、40391、5856などのセル値用に追加の列を作成したいので、25041が任意のdxs列の特定の行にある場合、値が1または0の列25041があります。私はこのコードを使用していますが、行数が少ない場合に機能します。

mat = X11.as_matrix(columns=None)
values, counts = np.unique(mat.astype(str), return_counts=True)

for x in values:
    X11[x] = X11.isin([x]).any(1).astype(int)

私はこのような結果を得ています:

dx1     dx2     dx3    dx4  0   25002   25041   25061   25081   3569    40391   42822   5856
25041   40391   5856    0   0   0       1       0       0       0          1        0       1
25041   40391   25081  5856 0   0       1       0       1       0            1      0       1
25041   40391   42822   0   0   0       1       0       0       0           1       1       0
25061   40391   0       0   0   0       0       1       0       0          1        0       0
25041   40391   0    5856   0   0       1       0       0       0          1        0       1
40391   25002 5856   3569   0   1       0       0       0       1          1        0       1

行の数が数千または数百万の場合、ハングして永久にかかり、結果が得られません。セルの値は列に固有ではなく、複数列で繰り返されることに注意してください。exの場合、40391はdx1だけでなく、dx2でも発生し、0や5856などでも発生します。上記のロジックを改善する方法はありますか?


これを解決する方法はありますか?私のデータがどんどん大きくなり、既存のソリューションがこれまでに生成されたダミー列を必要とするので、私はまだこれが解決するのを待っています。
Sanoj

回答:


6

パンダにはもっと多くのpythonicソリューションがあります...

これは私のラップトップの1000万行で1秒もかかりません:

for x in X11.E.unique():
    X11[x]=(X11.E==x).astype(int)
X11

詳細は次のとおりです。

シンプルな小さなデータフレーム-

import numpy as np
import pandas as pd

X11 = pd.DataFrame(np.random.randn(6,4), columns=list('ABCD'))
X11['E'] = [25223, 112233,25223,14333,14333,112233]
X11

シンプルな小さなデータフレーム

2値化法-

for x in X11.E.unique():
    X11[x]=(X11.E==x).astype(int)
X11

ここに画像の説明を入力してください

1,000万行のデータフレーム-

pd.set_option("display.max_rows",20)
X12 = pd.DataFrame(np.random.randn(10000000,4), columns=list('ABCD'))
foo = [25223, 112233,25223,14333,14333,112233]
bar=[]
import random
for x in range(10000000):
    bar.append(random.choice(foo))
X12['E'] = bar
X12

ここに画像の説明を入力してください

1000万行のデータフレームでの時限二値化(別名、ワンホットエンコーディング)-

import time
start = time.clock()

for x in X12.E.unique():
    X12[x]=(X12.E==x).astype(int)
elapsed = (time.clock() - start)

print "This is the time that this took in seconds: ",elapsed

X12

ここに画像の説明を入力してください

お役に立てれば!


これは、forループでダミー値(25041)と列名(つまり、dx1)を動的に取得する方法を示していません。一度に1つしか手に入りません。
Sanoj

今見てください。詳細をすべて追加しました。
AN6U5

「E」から行ったように1つの列のみに基づいてダミー値を作成する必要がある場合、ソリューションは適切に見えます。しかし、複数の列から作成する必要があり、それらのセル値が特定の列に一意ではない場合、それらのすべての列に対してコードを再度ループする必要がありますか?その場合、値の繰り返しはどのように処理されますか?それ以外の場合は、同じ名前で作成された前のダミー列が上書きされます。上記の質問の結果を追加して、混乱があったかどうかを明確にしました。とにかくそれを調べてくれてありがとう。
Sanoj

4

パンダのデータフレーム列からダミー変数を作成したいようです。幸い、パンダには特別なメソッドがありますget_dummies()。以下は、必要に応じて調整できるコードスニペットです。

import pandas as pd
data = pd.read_clipboard(sep=',')

#get the names of the first 3 columns
colN = data.columns.values[:3]

#make a copy of the dataframe
data_transformed = data

#the get_dummies method is doing the job for you
for column_name in colN:
    dummies = pd.get_dummies(data_transformed[column_name], prefix='value', prefix_sep='_')
    col_names_dummies = dummies.columns.values

    #then you can append new columns to the dataframe
    for i,value in enumerate(col_names_dummies):
        data_transformed[value] = dummies.iloc[:,i]

これは次の出力ですdata_transformed

         dx1    dx2    dx3   dx4    dx5    dx6    dx7  value_25041  value_25061  0  25041  40391   5856     0  V4511  V5867  30000            1            0   
    1  25041  40391  25081  5856   5363   3572      0            1            0   
    2  25041  40391  42822     0   5856      0      0            1            0   
    3  25061  40391      0     0      0      0      0            0            1   
    4  25041  40391      0  5856  25081  V4511  25051            1            0   

      value_40391  value_0  value_5856  value_25081  value_42822  
    0            1        0           1            0            0  
    1            1        0           0            1            0  
    2            1        0           0            0            1  
    3            1        1           0            0            0  
    4            1        1           0            0            0  

それは問題ないように見えますが、注意深く見ると、value_0の場合、すべての行に1がないことがわかります。すべての行に0が存在するため、value_0はすべての行に1を持つ必要があります。value_5856、Value_25081などでも同じです。このロジックは列から値を選択しているため、前に進む代わりに戻ることはないようです。
Sanoj

こんにちはSanoj。私のソリューションを使用して、私を反対票を投じることは本当に公平ではありません。あなたができる最低限のことは、新しい質問を開くのではなく、あなたが行った新しい進歩で質問を更新することです。人々に手伝ってもらいたいのなら、彼らと上手に遊ぶべきです。
michaelg

こんにちはマイケルド:私はあなたに投票するつもりはありませんでした。このソリューションは質問のとおり私のニーズを満たさなかったので、私はクリックサインを外しました。最初は大丈夫だと思っていましたが、後で調べたところ、上記の返信で述べたような矛盾が見つかりました。私はこれについての返事をもらっていなかったので、私は私の元の答えを述べ、必要な修正を加えた返信を含めて、新しい質問を作成しました。申し訳ありませんが、私はあなたの名前をそこで言及しませんでした。更新します。
Sanoj
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.