计算每个pandas行中从一个值到另一个值的更改次数,并将所有计数相加

问题描述 投票:1回答:3

我有一个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

步骤2:对于每个转置的df列,通过移动给定列的1行来创建临时列

步骤3:给定这样的列,对这样的列和临时列进行groupby然后计数

Step4:所有​​计数的总和

我认为可能有某种方式比这更有效。我可以提出你的建议吗?谢谢。

python pandas
3个回答
2
投票

如果你愿意的话,这是另一种解决方案:

  1. 连接原始数据帧和移位数据帧。
  2. 成对排列原始值和移位值
  3. tuple应用于每对
  4. 统计元组。 pd.concat([df, df.shift(axis=1)], keys=[1,2])\ .sort_index(level=1).dropna(axis=1).astype(int)\ .unstack().T.apply(tuple, axis=1).value_counts() #(2, 3) 2 #(3, 2) 2 #(3, 3) 1 #(3, 1) 1

3
投票

达蒙

M1:我在这里使用np.roll,然后结合使用stackvalue_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]))

2
投票

只是为了好玩,有一个巧妙的技巧:对(x,y)x,y in (1,2,3)x*4 + y独特决定。进一步来说

1,1 -> 5
1,2 -> 6
1,3 -> 7
2,1 -> 9
2,2 -> 10 
2,3 -> 11
3,1 -> 13
3,2 -> 14
3,3 -> 15

我们可以使用它并做

# compute values of these pairs across the dataset
new_df = (df[df.columns[:-1]].values * 4 + df[df.columns[1:]].values).flatten()

# count values
pd.Series(new_df).value_counts()

输出:

14    2
11    2
7     1
15    1
dtype: int64
© www.soinside.com 2019 - 2024. All rights reserved.