我的数据帧具有以下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:对于转置df的每一列,通过移动给定列的1行来创建一个临时列
第3步:给定这样的列,对这样的列和临时列进行groupby然后计数count
Step4:所有计数之和
我认为可能有比这更有效的方法。请问您有什么建议吗?谢谢。
答案 0 :(得分:3)
IIUC
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]))
答案 1 :(得分:2)
如果您愿意,这里是替代解决方案:
tuple
应用于每对计算元组。
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
答案 2 :(得分: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