Python 如何计算大熊猫状态变化的数量?

Python 如何计算大熊猫状态变化的数量?,python,pandas,dataframe,Python,Pandas,Dataframe,我有以下数据框,其中有0-1列。。我想 计算每列0->1,1->0的数量。在下面的数据帧中 “a”列状态更改编号为6,“b”列状态更改编号为3 ,“c”状态更改编号为2。。事实上我不知道怎么做 熊猫的代码 number a b c 1 0 0 0 2 1 0 1 3 0 1 1 4 1 1 1 5 0 0 0 6 1 0 0 7 0 1 0 事实上,我对熊猫没什么概念。。因为最近只用了r。 但现在我必须使用蟒蛇熊猫。所以有点

我有以下数据框,其中有0-1列。。我想 计算每列0->1,1->0的数量。在下面的数据帧中 “a”列状态更改编号为6,“b”列状态更改编号为3 ,“c”状态更改编号为2。。事实上我不知道怎么做 熊猫的代码

number a b c
1      0 0 0
2      1 0 1
3      0 1 1
4      1 1 1
5      0 0 0
6      1 0 0
7      0 1 0
事实上,我对熊猫没什么概念。。因为最近只用了r。 但现在我必须使用蟒蛇熊猫。所以有点困难 有人能帮忙吗?提前谢谢

使用并比较每个值,然后通过
sum
计算所有
True
值:

df = df[['a','b','c']].rolling(2).apply(lambda x: x[0] != x[-1], raw=True).sum().astype(int)
a    6
b    3
c    2
dtype: int64

你可以试着取和前一个不同的值,然后加上绝对值

df.diff().abs().sum().astype(int)
输出:

使用:

您还可以尝试以下方法:

((df!=df.shift()).cumsum() - 1).iloc[-1:]

shift
并比较:

df.ne(df.shift(-1)).sum(0) - 1

a    6
b    3
c    2
dtype: int64
…假设“number”是索引,否则在解决方案前面加上
df.set_index('number',inplace=True)

按位
xor
^
) 使用Numpy数组
df.values
并将移位的元素与
^

这是一个快速的解决方案

Xor具有这样一个属性,即所操作的两项中只有一项可以为真,如真值表所示

A B XOR
T T   F
T F   T
F T   T
F F   F

并以
0
/
1
形式复制

a = np.array([1, 1, 0, 0])
b = np.array([1, 0, 1, 0])

pd.DataFrame(dict(A=a, B=b, XOR=a ^ b))

   A  B  XOR
0  1  1    0
1  1  0    1
2  0  1    1
3  0  0    0

演示
时间测试

功能 测试 结果

.astype(int)
这里
sum
指的是
np.sum
,而不是Python的内置sum函数。
A B XOR
T T   F
T F   T
F T   T
F F   F
a = np.array([1, 1, 0, 0])
b = np.array([1, 0, 1, 0])

pd.DataFrame(dict(A=a, B=b, XOR=a ^ b))

   A  B  XOR
0  1  1    0
1  1  0    1
2  0  1    1
3  0  0    0
v = df.values

pd.Series((v[1:] ^ v[:-1]).sum(0), df.columns)

a    6
b    3
c    2
dtype: int64
def pir_xor(df):
  v = df.values
  return pd.Series((v[1:] ^ v[:-1]).sum(0), df.columns)

def pir_diff1(df):
  v = df.values
  return pd.Series(np.abs(np.diff(v, axis=0)).sum(0), df.columns)

def pir_diff2(df):
  v = df.values
  return pd.Series(np.diff(v.astype(np.bool), axis=0).sum(0), df.columns)

def cold(df):
  return df.ne(df.shift(-1)).sum(0) - 1

def jez(df):
  return df.rolling(2).apply(lambda x: x[0] != x[-1]).sum().astype(int)

def naga(df):
  return df.diff().abs().sum().astype(int)
np.random.seed([3, 1415])

idx = [10, 30, 100, 300, 1000, 3000, 10000, 30000, 100000, 300000]
col = 'pir_xor pir_diff1 pir_diff2 cold jez naga'.split()
res = pd.DataFrame(np.nan, idx, col)

for i in idx:
  df = pd.DataFrame(np.random.choice([0, 1], size=(i, 3)), columns=[*'abc'])
  for j in col:
    stmt = f"{j}(df)"
    setp = f"from __main__ import {j}, df"
    res.at[i, j] = timeit(stmt, setp, number=100)
res.div(res.min(1), 0)

        pir_xor  pir_diff1  pir_diff2       cold         jez      naga
10      1.06203   1.119769   1.000000  21.217555   16.768532  6.601518
30      1.00000   1.075406   1.115743  23.229013   18.844025  7.212369
100     1.00000   1.134082   1.174973  22.673289   21.478068  7.519898
300     1.00000   1.119153   1.166782  21.725495   26.293712  7.215490
1000    1.00000   1.106267   1.167786  18.394462   37.925160  6.284253
3000    1.00000   1.118554   1.342192  16.053097   64.953310  5.594610
10000   1.00000   1.163557   1.511631  12.008129  106.466636  4.503359
30000   1.00000   1.249835   1.431120   7.826387  118.380227  3.621455
100000  1.00000   1.275272   1.528840   6.690012  131.912349  3.150155
300000  1.00000   1.279373   1.528238   6.301007  140.667427  3.190868
res.plot(loglog=True, figsize=(15, 8))