繁体   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