pandas 如何隐藏水平单调数列?

wswtfjt7  于 2023-09-29  发布在  其他
关注(0)|答案(2)|浏览(82)

我的输入是df

COLUMN_1  COLUMN_2  COLUMN_3  COLUMN_4
0         0         1         0         2
1         1         1         2         3
2         1         2         3         2
3         1         2         4         5
4         4         5         8         8

我希望我可以隐藏(水平地,从左到右)差异等于1的单调序列。例如,如果在一行中我们有[4, 5, 8, 8](就像最后一个),那么相关的序列是[4, 5)。因此,我们需要用emty字符串隐藏数字4
我的预期输出是这样的:

COLUMN_1 COLUMN_2 COLUMN_3  COLUMN_4
0                 1        0         2
1        1                           3
2                          3         2
3                 2                  5
4                 5        8         8

说明:

我尝试了下面的代码,但我没有在正确的轨道,因为我得到了一个奇怪的布尔 Dataframe 。

df.diff(axis=1).eq(1).iloc[:, ::-1].cummax(axis=1).replace(True, '').iloc[:, ::-1]
fwzugrvs

fwzugrvs1#

import pandas as pd

df = pd.DataFrame({
    'COLUMN_1': [0, 1, 1, 1, 4],
    'COLUMN_2': [1, 1, 2, 2, 5],
    'COLUMN_3': [0, 2, 3, 4, 8],
    'COLUMN_4': [2, 3, 2, 5, 8]
})

df = df.astype(str)  # Convert DataFrame to string type

for col in range(1, df.shape[1]):
    mask = (df.iloc[:, col] == df.iloc[:, col-1].astype(int).add(1).astype(str))
    df.iloc[:, col-1] = df.iloc[:, col-1].where(~mask, '')
df.head()

输出

COLUMN_1 COLUMN_2 COLUMN_3 COLUMN_4
0                 1        0        2
1        1                          3
2                          3        2
3                 2                 5
4                 5        8        8
  • 它使用布尔值mask来标识需要用空字符串替换的元素。它还通过使用向量化操作来避免对行进行不必要的迭代。
  • 迭代每一列(从第二列开始)并创建一个布尔掩码,用于标识需要替换的元素。然后,它使用where方法将前一列中的元素替换为空字符串,其中掩码为True
ecbunoof

ecbunoof2#

您需要在diff中使用负句点,并结合mask

out = df.mask(df.diff(-1, axis=1).eq(-1), '')

或者,对于就地修改:

df[df.eq(df.shift(-1, axis=1)-1)] = ''

使用shift的变体:

out = df.mask(df.eq(df.shift(-1, axis=1)-1), '')

输出量:

COLUMN_1 COLUMN_2 COLUMN_3  COLUMN_4
0                 1        0         2
1        1                           3
2                          3         2
3                 2                  5
4                 5        8         8

中间体:

# df.diff(-1, axis=1)
   COLUMN_1  COLUMN_2  COLUMN_3  COLUMN_4
0        -1         1        -2       NaN
1         0        -1        -1       NaN
2        -1        -1         1       NaN
3        -1        -2        -1       NaN
4        -1        -3         0       NaN

# df.shift(-1, axis=1)
   COLUMN_1  COLUMN_2  COLUMN_3  COLUMN_4
0         1         0         2       NaN
1         1         2         3       NaN
2         2         3         2       NaN
3         2         4         5       NaN
4         5         8         8       NaN

相关问题