从数据框的“特定列”检查值,并将值从数组更新为第2列

时间:2019-06-05 14:44:33

标签: python python-3.x pandas dataframe

我有一个包含2列的数据框,其中A列和B列以及从A到P的字母数组,如下所示

    df = pd.DataFrame({
'Column_A':[0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
'Column_B':[]
})

该数组如下:

    label = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P']

预期输出为

    'A':[0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
'B':['A','A','A','A','A','E','E','E','E','E','I','I','I','I','I','M']

只要A列的值为1,B列的值就会更改,并且该值取自给定数组'label'

我已经尝试过将其用于循环

    for row in df.index:   
         try:
              if df.loc[row,'Column_A'] == 1:
                   df.at[row, 'Column_B'] = label[row+4]
                   print(label[row])
              else:
                   df.ColumnB.fillna('ffill')
         except IndexError:
              row = (row+4)%4
              df.at[row, 'Coumn_B'] = label[row]

如果它达到“标签”数组中的最后一个值,我也想回送。

3 个答案:

答案 0 :(得分:1)

选项1

cond1 = df.Column_A == 1
cond2 = df.index == 0
mappr = lambda x: label[x]

df.assign(Column_B=np.where(cond1 | cond2, df.index.map(mappr), np.nan)).ffill()

    Column_A Column_B
0          0        A
1          0        A
2          0        A
3          0        A
4          0        A
5          1        F
6          0        F
7          0        F
8          0        F
9          0        F
10         1        K
11         0        K
12         0        K
13         0        K
14         0        K
15         1        P

选项2

a = np.append(0, np.flatnonzero(df.Column_A))
b = df.Column_A.to_numpy().cumsum()
c = np.array(label)

df.assign(Column_B=c[a[b]])

    Column_A Column_B
0          0        A
1          0        A
2          0        A
3          0        A
4          0        A
5          1        F
6          0        F
7          0        F
8          0        F
9          0        F
10         1        K
11         0        K
12         0        K
13         0        K
14         0        K
15         1        P

答案 1 :(得分:1)

先将groupbytransform一起使用,然后将map

df.reset_index().groupby(df.Column_A.eq(1).cumsum())['index'].transform('first').map(dict(enumerate(label)))
Out[139]: 
0     A
1     A
2     A
3     A
4     A
5     F
6     F
7     F
8     F
9     F
10    K
11    K
12    K
13    K
14    K
15    P
Name: index, dtype: object

答案 2 :(得分:1)

一些可以解决问题的解决方案如下:

label=list('ABCDEFGHIJKLMNOP')
df = pd.DataFrame({
'Column_A': [0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
'Column_B': label
})

不确定,您对fillna打算做什么,因为我认为您不需要它。

max_index= len(label)
df['Column_B']='ffill'
lookup= 0
for row in df.index:
    if df.loc[row,'Column_A'] == 1:
       lookup= lookup+4 if lookup+4 < max_index else lookup%4
    df.at[row, 'Column_B'] = label[lookup]
    print(label[row])

在这种情况下,我也避免了异常处理,因为无需处理异常即可处理“索引溢出”。

顺便说一句。如果您有一个大型数据框,则可以通过消除一次查找来使代码更快(但您需要验证它是否确实运行得更快)。解决方案如下:

max_index= len(label)
df['Column_B']='ffill'
lookup= 0
for row, record in df.iterrows():
    if record['Column_A'] == 1:
       lookup= lookup+4 if lookup+4 < max_index else lookup%4
    df.at[row, 'Column_B'] = label[lookup]
    print(label[row])