![](/img/trans.png)
[英]Create new Python DataFrame column based on conditions of multiple other columns
[英]Vectorize operation to create multiple new columns based on different conditions in a dataframe in Python
我有一個 dataframe,如下所示:
+-----+---------+--------+-------------+
| Id | Record | Type | Status |
+-----+---------+--------+-------------+
| 111 | R1 | Email | Open |
| 123 | R2 | Event | Accepted |
| 234 | R3 | Story | Pending |
| 135 | R3 | Search | Click |
+-----+---------+--------+-------------+
It has around 1 million rows
記錄列只能有三個值,即“R1”、“R2”和“R3”。
對於記錄 R1,類型始終為“電子郵件”,狀態有多個值,其中我只對“打開”和“單擊”感興趣。
對於記錄 R2,類型始終為“事件”,狀態具有多個值,其中我只對“打開”和“已注冊”感興趣。
然而,對於記錄 R3,可以有多個類型值,即“搜索”、“故事”等,並且每種類型都有我感興趣的不同狀態值。
我想在以下條件下創建新的計數列:
如果記錄為“R1”,則 email_cnt = 1,否則為 0
如果記錄為“R2”,則 event_cnt = 1,否則為 0
如果記錄為“R3”且類型為“故事”,則 story_cnt = 1,否則為 0
如果記錄為“R3”且類型為“搜索”,則 search_cnt = 1,否則為 0,對於所有不同的 R3 類型,依此類推。
我已經使用iterrows遍歷 dataframe 的每一行並替換值。 我知道這不是最有效的方法,但我無法制定如何使用 apply 方法或進行矢量化來加速計算。
如果您知道更快/更好的方法,請提出建議。
下面是我的代碼:
df = pd.read_csv('file.csv')
# Create new metrics columns
tempcols = ['email_cnt', 'event_cnt', 'dm_cnt', 'enc_cnt', 'exp_cnt', 'orgsearch_cnt', 'orgsocial_cnt', 'paidsm_cnt', 'paidsearch_cnt', 'pd_cnt', 'smrtroom_cnt', 'stry_cnt', 'tm_cnt']
# Append new metrics in the existing campaigns dataframe
df = pd.concat([df, pd.DataFrame(columns=tempcols)])
# Values of Status column that we need
status_vals = ['Accepted', 'Call Completed', 'Commented', 'Declined', 'Liked', 'Responded', 'Shared']
for index, row in df.iterrows():
if((row['Record']=='R1') & (row['Status'] in ['Open', 'Click'])):
df.at[index, 'email_cnt'] = 1
if((row['Record']=='R2') & (row['Status'] in ['Open', 'Registered'])):
df.at[index, 'event_cnt'] = 1
if(row['Record']=='R3'):
if((row['Type']=='Story') & (row['Status'] in status_vals)):
df.at[index, 'stry_cnt'] = 1
if((row['Type']=='Search') & (row['Status'] in status_vals+['Downloaded', 'Registered'])):
df.at[index, 'search_cnt'] = 1
if((row['Type']=='Experience') & (row['Status'] in status_vals)):
df.at[index, 'exp_cnt'] = 1
df.fillna(0, inplace=True)
您可以列出您的條件並從中制作一個 DataFrame:
conditions=[
(df['Record'].eq('R1') & (df['Status'].isin(['Open', 'Click']))),
(df['Record'].eq('R2') & (df['Status'].isin(['Open', 'Registered']))),
(df['Record'].eq('R3') & df['Type'].eq('Story')),
(df['Record'].eq('R3') & df['Type'].eq('Search'))
]
out=pd.concat(conditions,axis=1).astype(int)
out.columns=['email_cnt', 'event_cnt', 'story_cnt', 'search_cnt']
或者
你可以使用np.where()
4次:
import numpy as np
df['email_cnt']=np.where((df['Record'].eq('R1') & (df['Status'].isin(['Open', 'Click']))),1,0)
df['event_cnt']=np.where((df['Record'].eq('R2') & (df['Status'].isin(['Open', 'Registered']))),1,0)
df['story_cnt']=np.where((df['Record'].eq('R3') & df['Type'].eq('Story')),1,0)
df['search_cnt']=np.where( (df['Record'].eq('R3') & df['Type'].eq('Search')),1,0)
注意:你也可以像 np.where 一樣使用loc
4 步
您可以使用以下方法創建所有新列:
new_cols = [col.lower() + '_cnt' for col in set(df['Type'])]
df = df.assign({col: 0 for col in new_cols})
然后使用以下命令用您的特定條件填充 1:
df.loc[(df['Record'] == 'R1') & (df['Type'] == 'Story') & df['Status'].isin(['Open', 'Click']), 'email_cnt'] = 1
因此,對於您擁有的所有條件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.