簡體   English   中英

數據框根據條件用值填充行

[英]Dataframe fill rows with values based on condition

假設我有這個數據框:

A | B | C
---------
n | b | c
n | b | c
n | b | c
s | b | c
n | b | c
n | b | c
n | b | c
e | b | c
n | b | c
n | b | c
s | b | c
n | b | c
n | b | c
n | b | c
e | b | c

我想用“x”填充和替換 A 列的行值。 要填充的行是“s”之前和“e”之后的行,而不是介於兩者之間的行。 所以結果會是這樣的:

A | B | C
---------
x | b | c
x | b | c
x | b | c
s | b | c
n | b | c
n | b | c
n | b | c
e | b | c
x | b | c
x | b | c
s | b | c
n | b | c
n | b | c
n | b | c
e | b | c

這是我嘗試過的:

def applyFunc(s):
    if 's' in str(s):
        return 'x'
    return ''

df['A'] = df['A'].apply(applyFunc)

但這只會替換有“s”的行。

首先找到值在 'e' 或 's' 之后的行:

A = d['A'] # enables shorter reference to df['A']
A.where(A.isin(['e', 's'])).ffill().fillna('e')
['e', 'e', 'e', 's', 's', 's', 's', 'e', 'e', 'e', 's', 's', 's', 's', 'e']

然后找到'n'在's'之后的位置並替換為'x':

df['new_A'] = A.mask((A.where(A.isin(['e', 's'])).ffill().fillna('e').eq('e')&A.eq('n')), 'x')

輸出:

    A  B  C new_A
0   n  b  c     x
1   n  b  c     x
2   n  b  c     x
3   s  b  c     s
4   n  b  c     n
5   n  b  c     n
6   n  b  c     n
7   e  b  c     e
8   n  b  c     x
9   n  b  c     x
10  s  b  c     s
11  n  b  c     n
12  n  b  c     n
13  n  b  c     n
14  e  b  c     e

注意。 為了清楚起見,我將輸出保存在一個新的列中,但真正的代碼應該是df['A'] = …

假設組內沒有重復se ,我們可以Series.mask se之間的n值。 我們可以通過比較seSeries.cumsum是否相等來跟蹤我們是否在se之間:

df['A'] = df['A'].mask(
    df['A'].eq('s').cumsum().eq(df['A'].eq('e').cumsum()) & df['A'].eq('n'),
    'x'
)

df

    A  B  C
0   x  b  c
1   x  b  c
2   x  b  c
3   s  b  c
4   n  b  c
5   n  b  c
6   n  b  c
7   e  b  c
8   x  b  c
9   x  b  c
10  s  b  c
11  n  b  c
12  n  b  c
13  n  b  c
14  e  b  c

步驟細分為列:

# See Where S are
df['S cumsum'] = df['A'].eq('s').cumsum()
# See where E are
df['E cumsum'] = df['A'].eq('e').cumsum()
# See where S and E are the same meaning we have seen both or neither but
# not one or the other
df['S == E cumsum'] = df['S cumsum'].eq(df['E cumsum'])
# See where A is n
df['S == E cumsum AND A == n'] = df['S == E cumsum'] & df['A'].eq('n')
    A  B  C  S cumsum  E cumsum  S == E cumsum  S == E cumsum AND A == n
0   n  b  c         0         0           True                      True
1   n  b  c         0         0           True                      True
2   n  b  c         0         0           True                      True
3   s  b  c         1         0          False                     False
4   n  b  c         1         0          False                     False
5   n  b  c         1         0          False                     False
6   n  b  c         1         0          False                     False
7   e  b  c         1         1           True                     False
8   n  b  c         1         1           True                      True
9   n  b  c         1         1           True                      True
10  s  b  c         2         1          False                     False
11  n  b  c         2         1          False                     False
12  n  b  c         2         1          False                     False
13  n  b  c         2         1          False                     False
14  e  b  c         2         2           True                     False

DataFrame 和導入:

import pandas as pd

df = pd.DataFrame({
    'A': ['n', 'n', 'n', 's', 'n', 'n', 'n', 'e', 'n', 'n', 's', 'n', 'n', 'n',
          'e'],
    'B': ['b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b',
          'b'],
    'C': ['c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c',
          'c']
})

如果有重復項,我們可以過濾掉所需的起始值和結束值( se )並只取偶數組: df

df = pd.DataFrame({
    'A': ['n', 'n', 'n', 's', 's', 'n', 'n', 'e', 'n', 'n', 's', 'n', 'n', 'e',
          'e'],
    'B': ['b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b',
          'b'],
    'C': ['c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c',
          'c']
})

    A  B  C
0   n  b  c
1   n  b  c
2   n  b  c
3   s  b  c
4   s  b  c  # Duplicate S
5   n  b  c
6   n  b  c
7   e  b  c
8   n  b  c
9   n  b  c
10  s  b  c
11  n  b  c
12  n  b  c
13  e  b  c
14  e  b  c  # Duplicate E

查找se並過濾以僅保留偶數組:

s = df.loc[df['A'].isin(['s', 'e']), 'A']
df['A'] = df['A'].mask(
    ((df.index.isin(s[s.ne(s.shift())].index).cumsum() % 2) == 0)
    & df['A'].eq('n'),
    'x'
)

df

    A  B  C
0   x  b  c
1   x  b  c
2   x  b  c
3   s  b  c
4   s  b  c
5   n  b  c
6   n  b  c
7   e  b  c
8   x  b  c
9   x  b  c
10  s  b  c
11  n  b  c
12  n  b  c
13  e  b  c
14  e  b  c

解決方案1:

df1.assign(col1=(df1.A=='s').cumsum())\
    .assign(col2=(df1.A=='e').cumsum().shift().fillna(0))\
    .assign(A=lambda dd:dd.A.mask(dd.col1==dd.col2,'x'))
        

   A    B   C  s    e
0   x   b    c  0  NaN
1   x   b    c  0  0.0
2   x   b    c  0  0.0
3   s   b    c  1  0.0
4   n   b    c  1  0.0
5   n   b    c  1  0.0
6   n   b    c  1  0.0
7   e   b    c  1  0.0
8   x   b    c  1 -1.0
9   x   b    c  1 -1.0
10  s   b    c  2 -1.0
11  n   b    c  2 -1.0
12  n   b    c  2 -1.0
13  n   b    c  2 -1.0
14  e   b    c  2 -1.0

解決方案2:

def function1(dd:pd.DataFrame):
    dd.loc[:dd.query("A=='s'").index.values[-1]-1,'A']='x'
    return dd.drop('col1',axis=1)

df1.assign(col1=(df1.A=='e').cumsum().shift()).groupby('col1').apply(function1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM