[英]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
)
我是使用iterrows
或apply
完成的。 这可能有效,但它需要很长时间,我真的需要通过一些 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)
在此先感谢您的帮助
一个客户可以在不同的日期拥有多个 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.