簡體   English   中英

如何將數據框單元格中的關鍵字分別轉換為自己的列

[英]How to convert keyword in cell of dataframe to own column each

我有一個如下數據框:

In[8]: df = pd.DataFrame({'transport': ['Car;Bike;Horse','Car','Car;Bike', 'Horse;Car']})
df
Out[8]:
    transport
 0  Car;Bike;Horse
 1  Car
 2  Car;Bike
 3  Horse;Car

我想將其轉換為如下形式:

In[9]: df2 = pd.DataFrame({'transport_car': [True,True,True,True],'transport_bike': [True,False,True,False], 'transport_horse': [True,False,False,True]} )
df2
Out[10]:
  transport_bike    transport_car   transport_horse
0   True                True            True
1   False               True            False
2   True                True            False
3   False               True            True

我有一個解決方案,但是感覺非常“亂砍”和“異常”。 (它適用於我的小型數據集)

In[11]:
# get set of all possible values
new_columns = set()
for element in set(df.transport.unique()):
    for transkey in str(element).split(';'):
        new_columns.add(transkey)
print(new_columns)

# Use broadcast to initialize all columns with default value.
for col in new_columns:
    df['trans_'+str(col).lower()] = False

# Change cells appropiate to keywords
for index, row in df.iterrows():
    for key in new_columns:
        if key in row.transport:
            df.set_value(index, 'trans_'+str(key).lower(), True)
df

Out[11]:
    transport     trans_bike    trans_car   trans_horse
0   Car;Bike;Horse  True          True          True
1   Car             False         True          False
2   Car;Bike        True          True          False
3   Horse;Car       False         True          True

我的目標是使用第二種表示形式進行評估,以回答諸如“汽車多久使用一次”,“汽車與馬一起使用多長時間”等問題。

這個這個答案表明使用pivoteval可能是eval的方法,但是我不確定。

那么,將DataFrame從第一種表示轉換為第二種表示的最佳方法是什么?

您可以對拆分后的字段作為索引的每個條目使用apply並構造一個Series。 這將導致以索引為列的數據幀:

df.transport.apply(lambda x: pd.Series(True, x.split(";"))).fillna(False)

在此處輸入圖片說明

我決定通過一個工作示例來擴展@Metropolis 的出色答案

In [249]: %paste
from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(min_df=1)
X = vectorizer.fit_transform(df.transport.str.replace(';',' '))

r = pd.DataFrame(X.toarray(), columns=vectorizer.get_feature_names())
## -- End pasted text --

In [250]: r
Out[250]:
   bike  car  horse
0     1    1      1
1     0    1      0
2     1    1      0
3     0    1      1

現在您可以將其重新加入源DF:

In [251]: df.join(r)
Out[251]:
        transport  bike  car  horse
0  Car;Bike;Horse     1    1      1
1             Car     0    1      0
2        Car;Bike     1    1      0
3       Horse;Car     0    1      1

時間:對於40K行DF:

In [254]: df = pd.concat([df] * 10**4, ignore_index=True)

In [255]: df.shape
Out[255]: (40000, 1)

In [256]: %timeit df.transport.apply(lambda x: pd.Series(True, x.split(";"))).fillna(False)
1 loop, best of 3: 33.8 s per loop

In [257]: %%timeit
     ...: vectorizer = CountVectorizer(min_df=1)
     ...: X = vectorizer.fit_transform(df.transport.str.replace(';',' '))
     ...: r = pd.DataFrame(X.toarray(), columns=vectorizer.get_feature_names())
     ...:
1 loop, best of 3: 732 ms per loop

我會考慮使用Scikit-learn提供的Count Vectorizer 矢量化器將構造一個矢量,其中每個索引均指一個術語,而值指的是該術語在記錄中的出現次數。

相對於其他答案中提出的本壘打方法,其優勢在於大型數據集的效率和可概括性。 顯然,缺點是帶來了額外的依賴性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM