计算 Pandas 列中值的变化次数
Count number of change in values in Pandas column
我有一个这样的df
name class date value
Andy A 20220101 0
Andy A 20220103 1
Andy A 20220104 0
Bob Z 20221120 0
Bob Z 20221121 0
Bob Z 20221125 0
Bob Z 20221127 1
列value
只取值0或1。对于每个组(由2列name
和class
定义),列date
按升序排列.我正在尝试为每个组计算比率:列 value
值变化的次数(0 -> 1 或 1 -> 0)除以包含数据的日期数。
对于上述数据框,组 (Andy, A) 在 3 天内更改了 2 次,因此比率为 2/3。 Group (Bob, Z) 4天换1次所以比例是1/4=0.25.
我想知道在 Pandas 中是否有有效的方法来做到这一点?
这个有效
# mark the changes in value
df['changes'] = df['value'].diff().ne(0).cumsum()
# count the number of changes and the number of values for each name
aggregated = df.groupby('name').agg({'changes':'nunique', 'value':'size'})
# by construction, we counted the original, so to count the "changes", we must subtract 1
aggregated['changes'] -= 1
# find the ratio
final = aggregated['changes'] / aggregated['value']
name
Andy 0.666667
Bob 0.250000
dtype: float64
你可以试试
out = (df
.groupby(['name', 'class']).apply(lambda g: g['value'].shift().bfill().ne(g['value']).sum()/g['date'].nunique())
.round(2)
.to_frame('ratio')
.reset_index())
print(out)
name class ratio
0 Andy A 0.67
1 Bob Z 0.25
我有一个这样的df
name class date value
Andy A 20220101 0
Andy A 20220103 1
Andy A 20220104 0
Bob Z 20221120 0
Bob Z 20221121 0
Bob Z 20221125 0
Bob Z 20221127 1
列value
只取值0或1。对于每个组(由2列name
和class
定义),列date
按升序排列.我正在尝试为每个组计算比率:列 value
值变化的次数(0 -> 1 或 1 -> 0)除以包含数据的日期数。
对于上述数据框,组 (Andy, A) 在 3 天内更改了 2 次,因此比率为 2/3。 Group (Bob, Z) 4天换1次所以比例是1/4=0.25.
我想知道在 Pandas 中是否有有效的方法来做到这一点?
这个有效
# mark the changes in value
df['changes'] = df['value'].diff().ne(0).cumsum()
# count the number of changes and the number of values for each name
aggregated = df.groupby('name').agg({'changes':'nunique', 'value':'size'})
# by construction, we counted the original, so to count the "changes", we must subtract 1
aggregated['changes'] -= 1
# find the ratio
final = aggregated['changes'] / aggregated['value']
name
Andy 0.666667
Bob 0.250000
dtype: float64
你可以试试
out = (df
.groupby(['name', 'class']).apply(lambda g: g['value'].shift().bfill().ne(g['value']).sum()/g['date'].nunique())
.round(2)
.to_frame('ratio')
.reset_index())
print(out)
name class ratio
0 Andy A 0.67
1 Bob Z 0.25