Skip to main content
 首页 » 编程设计

python之计算每个 pandas 行中从一个值到另一个值的变化次数并对所有计数求和

2025年05月04日14think

我有一个包含 3 个可能值(1、2、3)的数据框,如下所示

df = pd.DataFrame({"A": [1, 2], "B": [3, 3], "C": [2, 3], "D": [3, 2]}) 

有了这个数据框

A   B   C   D 
1   3   2   3 
2   3   3   2 

一个值到另一个值的计数是

第 0 行

1 -> 1 = 0   2 -> 1 = 0   3 -> 1 = 0 
1 -> 2 = 0   2 -> 2 = 0   3 -> 2 = 1 
1 -> 3 = 1   2 -> 3 = 1   3 -> 3 = 0 

第 1 行

1 -> 1 = 0   2 -> 1 = 0   3 -> 1 = 0 
1 -> 2 = 0   2 -> 2 = 0   3 -> 2 = 1 
1 -> 3 = 0   2 -> 3 = 1   3 -> 3 = 1 

然后我将这些计数加起来如下

总计

1 -> 1 = 0   2 -> 1 = 0   3 -> 1 = 0 
1 -> 2 = 0   2 -> 2 = 0   3 -> 2 = 2 
1 -> 3 = 1   2 -> 3 = 2   3 -> 3 = 1 

我能想到的大概流程如下

第一步:转置df

Step2:对于transposed df的每一列,通过移动给定列的1行创建一个临时列

Step3:给定这样一个列,对这样一个列和一个临时列做groupby然后count count

Step4:所有​​计数的总和

我认为可能有比这更有效的方法。我可以有你的建议吗?谢谢。

请您参考如下方法:

国际联合会

M1 : 我在这里使用 np.roll ,然后在合并后我们使用 stack 和 value_counts

df=df.astype(str) 
df1=df.copy() 
df1[:]=np.roll(df1.values,axis=1,shift=-1) 
df1.iloc[:,-1]=np.NaN 
(df+'->'+df1).stack().value_counts() 
3->2    2 
2->3    2 
3->3    1 
1->3    1 
dtype: int64 

M2:如果 roll 很难让它工作,请尝试 shfit

df = df.astype(str) 
df1 = df.copy() 
df1=df1.shift(-1,axis=1) 
print((df + '->' + df1).stack().value_counts()) 
3->2    2 
2->3    2 
3->3    1 
1->3    1 
dtype: int64 

M3:为速度而构建 numpy

df = pd.DataFrame({"A": [1, 2], "B": [3, 3], "C": [2, 3], "D": [3, 2]}) 
 
df1 = df.copy() 
df1=df1.shift(-1,axis=1) 
 
np.unique(np.rec.fromarrays((df.values[:,:-1],df1.values[:,:-1])),return_counts=True) 
(rec.array([(1, 3.), (2, 3.), (3, 2.), (3, 3.)], 
          dtype=[('f0', '<i8'), ('f1', '<f8')]), array([1, 2, 2, 1]))