簡體   English   中英

Pandas 根據來自另一個 dataframe 的計數和條件創建新列

[英]Pandas Create new column based on a count and a condition from another dataframe

問題

我有一個 dataframe df ,產品如下:

ID  DATE        TYPE    Client_ID
1   2015-01-15  A       johndoe
2   2009-01-15  C       johndoe
3   2015-03-12  C       johndoe
4   2010-01-01  B       johndoe
5   2017-01-01  B       johndoe
6   2018-01-01  A       markdoe
7   2019-01-01  C       johndoe
8   2012-01-01  C       markdoe

從這個我創建了一個 dataframe ,只有 A 型產品df-A

ID  DATE        TYPE    Client_ID
1   2015-01-15  A       johndoe
6   2018-01-01  A       markdoe

我想要創建df-A 2 個變量,這些變量計算客戶擁有的 B 型和 C 型產品的日期低於或等於分析的 A 產品的數量。 我想要的結果:

ID  DATE        TYPE    Client_ID   NB-B    NB-C
1   2015-01-15  A       johndoe     1       1
6   2018-01-01  A       markdoe     0       1

第一行的NB-B為 1,因為johndoe有 2 個 B 產品,但只有一個的Date <= 2015-01-15 (此產品ID=4 ,日期為2010-01-01

我嘗試了什么:

我是使用iterrowsapply完成的。 這可能有效,但它需要很長時間,我真的需要通過一些 groupby 和聚合使其更快。

for index, row in df-A.iterrows():
    row['NB-B'] = df[(df['ID'] == row['ID']) & (df['DATE'] <= row['DATE'])].groupby('TYPE').count()['ID'].loc['B']

apply相同

def B(x):
    return(row['NB-B'] = df[(df['ID'] == x['ID']) & (df['DATE'] <= x['DATE'])].groupby('TYPE').count()['ID'].loc['B'])

df-A.apply(lambda x: B(x), axis=1)

在此先感謝您的幫助

編輯:@Quang Hoang 回答后的詳細信息

一個客戶可以在不同的日期擁有多個 A 型產品(我沒有提到它是為了簡化,因為問題已經很復雜,我沒想到會做出很大的改變)。 另外,我想像Bs和Cs一樣計算客戶購買新產品后擁有的A產品的數量。

例子:

ID  DATE        TYPE    Client_ID
1   2015-01-15  A       johndoe
2   2009-01-15  C       johndoe
3   2015-03-12  C       johndoe
4   2010-01-01  B       johndoe
5   2017-01-01  B       johndoe
6   2020-01-01  A       johndoe
7   2019-01-01  C       johndoe

預期結果:

ID  DATE        TYPE    Client_ID   NB-A   NB-B    NB-C
1   2015-01-15  A       johndoe     1      1       1
6   2018-01-01  A       johndoe     2      2       3

這個細節很重要,因為應用您的代碼,我收到以下錯誤: Reindexing only valid with uniquely valued Index objects因為Client_ID成為s的新索引,它不是唯一的。

我試圖解決這個問題,但沒有成功。

讓我們試試 pivot_table 並加入:

# extract the A types
aType = df.TYPE.eq('A')
s = df[aType].set_index('Client_ID')

(df[~aType].assign(valid=lambda x: x['DATE'].le(x['Client_ID'].map(s['DATE'])).astype(int))
   .pivot_table(index='Client_ID',columns='TYPE',
                values='valid', aggfunc='max',
                fill_value=0)
   .add_prefix('NB_')
   .join(s)
   .reset_index()
)

Output:

  Client_ID  NB_B  NB_C  ID        DATE TYPE
0   johndoe     1     1   1  2015-01-15    A
1   markdoe     0     1   6  2018-01-01    A

你可以嘗試使用

Pandas.Series.str.count("string") 

您提取要計為系列的列,然后應用serie.str.count("the string you are looking for")

series = df["Client_ID"] 
  
count = series.str.count("johndoe")

您可以使用循環獲取“Client_ID”系列中的所有名稱

這將計算“Client_ID”列中出現的所有“johndoe”

暫無
暫無

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

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