首页 > 解决方案 > 数据帧分割和丢弃

问题描述

我在熊猫中有以下数据框:

A = [1,10,23,45,24,24,55,67,73,26,13,96,53,23,24,43,90], 
B = [24,23,29, BW,49,59,72, BW,9,183,17, txt,2,49,BW,479,BW]

我想创建一个新列,在该列中,我想根据 B 列上的条件从 A 列中获取值。条件是如果两个连续的“BW”之间没有“txt”,那么我将在 C 列上有那些。但是如果在两个连续的 ''BW'' 之间有 ''txt'',我想删除所有这些值。所以预期的输出应该是这样的:

A = [1,10,23,45,24,24,55,67,73,26,13,96,53,23,24,43,90], 
B = [24,23,29, BW,49,59,72, BW,9,183,17, txt,2,49,BW,479,BW]
C = [1,10,23, BW, 24,24,55, BW, nan, nan, nan, nan, nan, nan, BW, 43,BW]

我不知道该怎么做。任何帮助深表感谢。

标签: pythonpandasdataframeiteration

解决方案


我不知道这是否是最有效的方法,但是您可以创建一个新列,该列称为mask从映射列 B 中的值,方法如下:'BW'to True'txt'toFalse和所有其他值 to np.nan

然后,如果您从 向前填充 NaN,从mask向后填充 NaNmask并在逻辑上组合结果(只要向前或向后填充的列之一为 False,就设置为 True),您可以创建一个名为final_maskwhere all of the包含txt的连续BW之间的值用True填充。

然后,您可以使用.apply仅在final_mask为 False 且 B 列不是“BW”时选择 A 列的值,如果 final_mask为 False 且 B 列为“BW”,则选择 B 列,np.nan否则。

import numpy as np
import pandas as pd

A = [1,10,23,45,24,24,55,67,73,26,13,96,53,23,24,43,90]
B = [24,23,29, 'BW',49,59,72, 'BW',9,183,17, 'txt',2,49,'BW',479,'BW']
df = pd.DataFrame({'A':A,'B':B})

df["mask"] = df["B"].apply(lambda x: True if x == 'BW' else False if x == 'txt' else np.nan)
df["ffill"] = df["mask"].fillna(method="ffill")
df["bfill"] = df["mask"].fillna(method="bfill")
df["final_mask"] = (df["ffill"] == False) | (df["bfill"] == False)

df["C"] = df.apply(lambda x: x['A'] if (
    (x['final_mask'] == False) & (x['B'] != 'BW')) 
    else x['B'] if ((x['final_mask'] == False) & (x['B'] == 'BW')) 
    else np.nan, axis=1
)

>>> df
     A    B   mask  ffill  bfill  final_mask    C
0    1   24    NaN    NaN   True       False    1
1   10   23    NaN    NaN   True       False   10
2   23   29    NaN    NaN   True       False   23
3   45   BW   True   True   True       False   BW
4   24   49    NaN   True   True       False   24
5   24   59    NaN   True   True       False   24
6   55   72    NaN   True   True       False   55
7   67   BW   True   True   True       False   BW
8   73    9    NaN   True  False        True  NaN
9   26  183    NaN   True  False        True  NaN
10  13   17    NaN   True  False        True  NaN
11  96  txt  False  False  False        True  NaN
12  53    2    NaN  False   True        True  NaN
13  23   49    NaN  False   True        True  NaN
14  24   BW   True   True   True       False   BW
15  43  479    NaN   True   True       False   43
16  90   BW   True   True   True       False   BW

删除我们一路创建的列:

df.drop(columns=['mask','ffill','bfill','final_mask'])

     A    B    C
0    1   24    1
1   10   23   10
2   23   29   23
3   45   BW   BW
4   24   49   24
5   24   59   24
6   55   72   55
7   67   BW   BW
8   73    9  NaN
9   26  183  NaN
10  13   17  NaN
11  96  txt  NaN
12  53    2  NaN
13  23   49  NaN
14  24   BW   BW
15  43  479   43
16  90   BW   BW

推荐阅读