Membuat kolom baru dengan mengulangi baris dalam bingkai data panda

10

Saya memiliki bingkai data panda (X11) seperti ini: Sebenarnya saya memiliki 99 kolom hingga 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

Saya ingin membuat kolom tambahan untuk nilai sel seperti 25041.40391.5856 dll. Jadi akan ada kolom 25041 dengan nilai 1 atau 0 jika 25041 terjadi di baris tertentu di setiap kolom dxs. Saya menggunakan kode ini dan berfungsi ketika jumlah baris lebih sedikit.

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)

Saya mendapatkan hasil seperti ini:

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

Ketika jumlah baris ribuan atau jutaan, itu hang dan memakan waktu selamanya dan saya tidak mendapatkan hasil apa pun. Harap lihat bahwa nilai sel tidak unik untuk kolom, alih-alih diulang dalam multi kolom. Sebagai contoh, 40391 terjadi di dx1 dan juga di dx2 dan seterusnya untuk 0 dan 5856 dll. Adakah cara untuk meningkatkan logika yang disebutkan di atas?

Sanoj
sumber
Ada ide untuk mengatasi ini? Saya masih menunggu ini untuk menyelesaikan karena data saya semakin besar dan lebih besar dan solusi yang ada diperlukan untuk kolom dummy yang pernah dihasilkan.
Sanoj

Jawaban:

6

Ada solusi pythonic yang jauh lebih banyak di panda ...

Ini membutuhkan waktu kurang dari satu detik pada 10 Juta baris di laptop saya:

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

Berikut detailnya:

Kerangka data kecil sederhana -

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

bingkai data kecil sederhana

Metode binarisasi -

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

masukkan deskripsi gambar di sini

Bingkai data dengan 10 Juta baris -

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

masukkan deskripsi gambar di sini

Binarisasi waktu (alias penyandian satu panas) pada 10 juta baris data -

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

masukkan deskripsi gambar di sini

Semoga ini membantu!

AN6U5
sumber
Ini tidak mengatakan bagaimana Anda akan secara dinamis mendapatkan nilai dummy (25041) dan nama kolom (yaitu dx1) keduanya di loop for. Saya hanya bisa mendapatkan satu per satu.
Sanoj
Lihatlah sekarang. Saya menambahkan semua detail.
AN6U5
Solusi Anda terlihat bagus jika saya perlu membuat nilai dummy berdasarkan dalam satu kolom saja seperti yang Anda lakukan dari "E". Tetapi ketika saya harus membuatnya dari beberapa kolom dan nilai-nilai sel itu tidak unik untuk kolom tertentu maka apakah saya perlu mengulang kode Anda lagi untuk semua kolom itu? Jika demikian, lalu bagaimana pengulangan nilai akan dijaga? Kalau tidak, ia akan menulis kolom boneka sebelumnya yang dibuat dengan nama yang sama. Saya telah menambahkan hasil saya pada pertanyaan di atas untuk memperjelas jika ada kebingungan. Bagaimanapun, terima kasih untuk Anda melihatnya.
Sanoj
4

Sepertinya Anda ingin membuat variabel dummy dari kolom dataframe panda. Untungnya, panda memiliki metode khusus untuk itu: get_dummies(). Berikut ini cuplikan kode yang dapat Anda sesuaikan untuk kebutuhan Anda:

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]

Ini adalah output dari 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  
michaelg
sumber
Ini terlihat OK tetapi jika Anda akan melihat dengan hati-hati maka Anda akan menemukan bahwa untuk value_0, tidak ada 1 di semua baris. Karena 0 ada di semua baris maka value_0 harus memiliki 1 di semua baris. Sama untuk value_5856, Value_25081 dll. Tampaknya logika ini memilih nilai dari sebuah kolom dan kemudian tidak akan kembali, sebaliknya bergerak maju.
Sanoj
Hai Sanoj. Tidaklah adil untuk menggunakan solusi saya dan memilih saya. Paling tidak yang dapat Anda lakukan adalah memperbarui pertanyaan Anda dengan kemajuan baru yang Anda buat alih-alih membuka pertanyaan baru. Jika Anda ingin orang lain membantu Anda, Anda harus bermain baik dengan mereka.
michaelg
Halo michaeld: Saya tidak punya niat untuk memilih Anda. Saya hanya melepas tanda klik karena solusi ini tidak memenuhi kebutuhan saya seperti yang ditanyakan. Awalnya saya berpikir OK tapi kemudian ketika saya selidiki saya menemukan perbedaan seperti yang disebutkan dalam balasan di atas. Saya tidak mendapatkan balasan dari ini karena itu saya membuat pertanyaan baru di mana saya menyebutkan jawaban asli saya dan memasukkan balasan Anda dengan koreksi yang diperlukan. Maaf saya tidak menyebutkan nama Anda di sana. Saya akan memperbarui itu.
Sanoj