计算 Pandas Dataframe 中连续 1 和 0 的最大数量

数据挖掘 Python 熊猫 预处理 麻木的
2021-09-18 09:24:59

嘿,我有以下数据集

import pandas as pd
df = pd.DataFrame({    
'column1': [0,0,1,0,1,0,0,1,1,0,1,1,1]})

我希望能够计算连续 1 和 0 的数量并生成 2 列,如下所示:

consec0: 1,2,_,1,_,1,2,_,_,1,_,_,_
consec1: _,_,1,_,1,_,_,1,2_,1,2,3

然后我想获取最大连续数并创建两个列表:

max_consec0: 2,1,2,1
max_consec1: 1,1,2,3

我的数据集最终将只是 max_consec0 和 max_consec1

3个回答

要检查值是否已更改,您可以使用.diff并检查它是否非零.ne(0)NaN顶部的 将被视为与零不同),然后使用 计算更改.cumsum,如下所示:

df['counter'] = df.diff().ne(0).cumsum()

之后,您可以创建第二个数据框,其中索引是连续值组,列值是值(在您的情况下为 0 或 1)和长度(这是您最终想要的):

df2 = df.groupby('counter')['column1'].min().to_frame(name='value').join(
df.groupby('counter')['column1'].count().rename('number'))

结果max_consec0, max_consec1只是列中的值,按[number]列过滤[value]

max_consec0 = df2[df2['value']==0]['number'].tolist()
max_consec1 = df2[df2['value']==1]['number'].tolist()

您可以根据需要验证结果是否为[2, 1, 2, 1][1, 1, 2, 3]

对于此类问题,您可以使用np.where多个布尔表达式来获得答案。

#1 我们需要测试列是否等于您的目标值, 0 or 1

其次,我们必须确保列值不等于上面的列值。

第三,对于任何不等于我们输入值的值,我们返回一个 nan,因为它更容易与数值一起使用。

import numpy as np

df['col2'] = np.where(
    df["column1"].eq(0),
    df.groupby(df.column1.ne(df.column1.shift()).cumsum()).cumcount() + 1,
    np.nan,
)

df['col3'] = np.where(
    df["column1"].eq(1),
    df.groupby(df.column1.ne(df.column1.shift()).cumsum()).cumcount() + 1,
    np.nan,
)

print(df)

   column1  col2  col3
0         0   1.0   NaN
1         0   2.0   NaN
2         1   NaN   1.0
3         0   1.0   NaN
4         1   NaN   1.0
5         0   1.0   NaN
6         0   2.0   NaN
7         1   NaN   1.0
8         1   NaN   2.0
9         0   1.0   NaN
10        1   NaN   1.0
11        1   NaN   2.0
12        1   NaN   3.0

我们需要在空白行之前为每组数字创建一个代理键,并取每组的最大值。

df.assign(
    key1=df.groupby(df["col2"].isnull())["col2"].transform("cumcount").cumsum()
).groupby("key1")["col2"].max().dropna()

[2.0, 1.0, 2.0, 1.0]

df.assign(
    key2=df.groupby(df["col3"].isnull())["col3"].transform("cumcount").cumsum()
).groupby("key2")["col3"].max().dropna().tolist()

[1.0, 1.0, 2.0, 3.0]

你可以试试这个实现:

num0=0
num1=0
consec0=[]
consec1=[]
for i in range(len(df)):
  if(df.iloc[i,0])==0:
    num0=num0+1;
    num1=0;
  if(df.iloc[i,0])==1:
    num0=0;
    num1=num1+1;
  consec0.append(num0)
  consec1.append(num1)
df['consec0']=consec0
df['consec1']=consec1
max_consec0=df['consec0'].max()
max_consec1=df['consec1'].max()