2017-09-06 108 views
3

我有一個查詢該大熊貓據幀:如何將一列字符串轉換爲數字?

| name | event | 
---------------------------- 
| name_1  | event_1  | 
| name_1  | event_2  | 
| name_2  | event_1  | 

我需要列事件轉換爲數值,或東西,看起來像這樣:

| name | event_1 | event_2 | 
------------------------------- 
| name_1 | 1  | 0  | 
| name_1 | 0  | 1  | 
| name_2 | 1  | 0  | 

在軟件rapidminer,我可以做這與運算符「名義到數字」,所以我假設在Python中轉換列的類型應該是有效的,但我可以被誤認爲。

在最後,這個想法是讓在列值與相同名稱的總和,並有作爲結果的表看起來應該像這樣的:

| name | event_1 | event_2 | 
------------------------------- 
| name_1 | 1  | 1  | 
| name_2 | 1  | 0  | 

有一個返回預期的功能?

重要的是:我不能做事件的簡單計數,因爲我不認識他們,事件是用戶

編輯不同:以及感謝球員,我可以看到有多種方式做這個,你們可以說哪一個是pythonic的方式嗎?

回答

6

做的某些方面,它

1)

In [366]: pd.crosstab(df.name, df.event) 
Out[366]: 
event event_1 event_2 
name 
name_1  1  1 
name_2  1  0 

2)

In [367]: df.groupby(['name', 'event']).size().unstack(fill_value=0) 
Out[367]: 
event event_1 event_2 
name 
name_1  1  1 
name_2  1  0 

3)

In [368]: df.pivot_table(index='name', columns='event', aggfunc=len, fill_value=0) 
Out[368]: 
event event_1 event_2 
name 
name_1  1  1 
name_2  1  0 

4)

In [369]: df.assign(v=1).pivot(index='name', columns='event', values='v').fillna(0) 
Out[369]: 
event event_1 event_2 
name 
name_1  1.0  1.0 
name_2  1.0  0.0 
+0

**警告:** * 4)*只適用如果每個組合都是唯一的,不會聚集。 – piRSquared

+0

另外,用''size'代替'len' ......'df.pivot_table(index ='name',columns ='event',aggfunc ='size',fill_value = 0)'。我的時間表做出這個假設。 – piRSquared

5

選項1
pir1pir1_5

df.set_index('name').event.str.get_dummies() 

     event_1 event_2 
name      
name_1  1  0 
name_1  0  1 
name_2  1  0 

然後,你可以在整個索引

df.set_index('name').event.str.get_dummies().sum(level=0) 

     event_1 event_2 
name      
name_1  1  1 
name_2  1  0 
總結

選項2
pir2
或者你可以點積

pd.get_dummies(df.name).T.dot(pd.get_dummies(df.event)) 

     event_1 event_2 
name_1  1  1 
name_2  1  0 

選項3
pir3
高級模式

i, r = pd.factorize(df.name.values) 
j, c = pd.factorize(df.event.values) 
n, m = r.size, c.size 

b = np.bincount(i * m + j, minlength=n * m).reshape(n, m) 

pd.DataFrame(b, r, c) 

     event_1 event_2 
name_1  1  1 
name_2  1  0 

時序

res.plot(loglog=True) 

enter image description here

res.div(res.min(1), 0) 

      pir1  pir2 pir3  john1  john2  john3 
10  9.948396 3.399913 1.0 20.478368 4.460466 10.642113 
30  9.350524 2.681178 1.0 16.589248 3.847666 9.168907 
100 11.414536 3.079463 1.0 18.076040 4.277752 9.949305 
300 15.769594 2.940529 1.0 16.745889 3.945470 9.069265 
1000 26.869451 2.617564 1.0 12.789570 3.236390 7.279205 
3000 42.229542 2.099541 1.0 8.716600 2.429847 4.785814 
10000 52.571678 1.716088 1.0 4.597598 1.691989 2.800455 
30000 58.644764 1.469827 1.0 2.818744 1.535012 1.929452 

功能

pir1 = lambda df: df.set_index('name').event.str.get_dummies().sum(level=0) 
pir1_5 = lambda df: pd.get_dummies(df.set_index('name').event).sum(level=0) 
pir2 = lambda df: pd.get_dummies(df.name).T.dot(pd.get_dummies(df.event)) 

def pir3(df): 
    i, r = pd.factorize(df.name.values) 
    j, c = pd.factorize(df.event.values) 
    n, m = r.size, c.size 

    b = np.bincount(i * m + j, minlength=n * m).reshape(n, m) 

    return pd.DataFrame(b, r, c) 

john1 = lambda df: pd.crosstab(df.name, df.event) 
john2 = lambda df: df.groupby(['name', 'event']).size().unstack(fill_value=0) 
john3 = lambda df: df.pivot_table(index='name', columns='event', aggfunc='size', fill_value=0) 

測試

res = pd.DataFrame(
    index=[10, 30, 100, 300, 1000, 3000, 10000, 30000], 
    columns='pir1 pir2 pir3 john1 john2 john3'.split(), 
    dtype=float 
) 

for i in res.index: 
    d = pd.concat([df] * i, ignore_index=True) 
    for j in res.columns: 
     stmt = '{}(d)'.format(j) 
     setp = 'from __main__ import d, {}'.format(j) 
     res.at[i, j] = timeit(stmt, setp, number=100) 
0

你問了Python的方式,我想在Python這種方式是使用TECHNIC稱爲一個熱碼本的技術方法在圖書館很好地落實喜歡sklearn和一個後熱編碼您將需要按第一列對數據幀進行分組並應用求和函數。

這裏是一個代碼:

import pandas as pd #the useful libraries 
import numpy as np 
from sklearn.preprocessing import LabelBinarizer #form sklmearn 
dataset = pd.DataFrame([['name_1', 'event_1' ], ['name_1', 'event_2'], ['name_2', 'event_1']], columns=['name', 'event'], index=[1, 2, 3]) 
data = dataset['event'] #just reproduce your dataframe 
enc = LabelBinarizer(neg_label=0) 
dataset['event_2'] = enc.fit_transform(data) 
event_two = dataset['event_2'] 
dataset['event_1'] = (~event_two.astype(np.bool)).astype(np.int64) #this is a tip to reproduce the event_1 columns 
dataset = dataset.groupby('name').sum() 
dataset.reset_index(inplace=True) 

,輸出是:

enter image description here

相關問題