Tạo các cột mới bằng cách lặp qua các hàng trong khung dữ liệu gấu trúc


10

Tôi có khung dữ liệu gấu trúc (X11) như thế này: Thực tế tôi có 99 cột lên đến 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

Tôi muốn tạo (các) cột bổ sung cho các giá trị ô như 25041,40391,5856, v.v. Vì vậy, sẽ có một cột 25041 với giá trị là 1 hoặc 0 nếu 25041 xảy ra trong hàng cụ thể đó trong bất kỳ cột dxs nào. Tôi đang sử dụng mã này và nó hoạt động khi số lượng hàng ít hơn.

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)

Tôi nhận được kết quả như thế này:

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

Khi số lượng hàng là hàng ngàn hoặc hàng triệu, nó bị treo và mất mãi mãi và tôi không nhận được bất kỳ kết quả nào. Vui lòng xem các giá trị ô không phải là duy nhất cho cột, thay vào đó lặp lại trong nhiều cột. Đối với ex, 40391 đang xảy ra trong dx1 cũng như trong dx2 và cứ thế cho 0 và 5856, v.v ... Bạn có ý tưởng nào để cải thiện logic được đề cập ở trên không?


Bất kỳ ý tưởng làm thế nào để giải quyết điều này? Tôi vẫn đang chờ đợi điều này được giải quyết vì dữ liệu của tôi ngày càng lớn hơn và giải pháp hiện tại cần có để tạo ra các cột giả.
Sanoj

Câu trả lời:


6

Có một giải pháp pythonic nhiều hơn trong gấu trúc ...

Việc này mất chưa đến một giây trên 10 triệu hàng trên máy tính xách tay của tôi:

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

Dưới đây là các chi tiết được trình bày:

Khung dữ liệu nhỏ đơn giản -

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

khung dữ liệu nhỏ đơn giản

Phương pháp Binarization -

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

nhập mô tả hình ảnh ở đây

Khung dữ liệu với 10 triệu hàng -

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

nhập mô tả hình ảnh ở đây

Tính thời gian nhị phân (hay còn gọi là mã hóa một lần nóng) trên khung dữ liệu 10 triệu hàng -

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

nhập mô tả hình ảnh ở đây

Hi vọng điêu nay co ich!


Điều này không nói làm thế nào bạn sẽ tự động nhận được giá trị giả (25041) và tên cột (tức là dx1) cả trong vòng lặp for. Tôi chỉ có thể nhận được một lúc.
Sanoj

Hãy xem ngay bây giờ. Tôi đã thêm tất cả các chi tiết.
AN6U5

Giải pháp của bạn có vẻ tốt nếu tôi cần tạo các giá trị giả chỉ dựa trên một cột như bạn đã thực hiện từ "E". Nhưng khi tôi phải tạo nó từ nhiều cột và các giá trị ô đó không phải là duy nhất cho một cột cụ thể thì tôi có cần lặp lại mã của bạn cho tất cả các cột đó không? Nếu đó là trường hợp thì việc lặp lại các giá trị sẽ được quan tâm như thế nào? Nếu không, nó sẽ ghi lại cột giả trước đó được tạo với cùng tên. Tôi đã thêm kết quả của mình trong câu hỏi ở trên để làm rõ nếu có bất kỳ sự nhầm lẫn nào. Dù sao cũng cảm ơn bạn đã nhìn vào nó.
Sanoj

4

Có vẻ như bạn muốn tạo biến giả từ cột dataframe gấu trúc. May mắn thay, gấu trúc có một phương pháp đặc biệt cho nó : get_dummies(). Đây là một đoạn mã mà bạn có thể điều chỉnh cho nhu cầu của mình:

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]

Đây là đầu ra của 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  

Có vẻ ổn nhưng nếu bạn sẽ xem kỹ thì bạn sẽ thấy rằng với value_0, nó không có 1 trong tất cả các hàng. Vì 0 có mặt trong tất cả các hàng do đó value_0 nên có 1 trong tất cả các hàng. Tương tự với value_5856, Value_25081, v.v ... Có vẻ như logic này đang chọn các giá trị từ một cột và sau đó không quay lại thay vào đó di chuyển về phía trước.
Sanoj

Xin chào Sanoj. Thật không công bằng khi sử dụng giải pháp của tôi và bỏ phiếu cho tôi. Ít nhất bạn có thể làm là cập nhật câu hỏi của bạn với tiến trình mới bạn đã thực hiện thay vì mở một câu hỏi mới. Nếu bạn muốn mọi người giúp đỡ bạn, bạn nên chơi đẹp với họ.
michaelg

Xin chào michaeld: Tôi không có ý định bỏ phiếu cho bạn. Tôi vừa gỡ bỏ dấu hiệu nhấp chuột vì giải pháp này không đáp ứng nhu cầu của tôi như được hỏi trong câu hỏi. Ban đầu tôi nghĩ OK nhưng sau này khi điều tra tôi đã tìm thấy sự khác biệt như đã đề cập trong bài trả lời ở trên. Tôi đã không nhận được bất kỳ câu trả lời nào vì vậy tôi đã tạo ra một câu hỏi mới trong đó tôi đã đề cập đến câu trả lời ban đầu của mình và bao gồm câu trả lời của bạn với sự điều chỉnh cần thiết. Xin lỗi tôi đã không đề cập đến tên của bạn ở đó. Tôi sẽ cập nhật điều đó.
Sanoj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.