同时迭代两列,并根据条件更改单元格的值



>我有一个以下格式的数据帧:

索引对象 1-长度 对象 1-高度 对象 2-2020194 20 50
长度 对象2-高度
019 492152
150 2151
2512052
3501952
2052

让我们试试:

# length like columns
l = df.filter(like='-Length').columns
# corresponding height columns
h = l.str.rstrip('Length') + 'Height'
# create boolean mask
m = (df[l].ge(20).values & df[h].ge(50).values).astype(int)
# assign the values
df[h], df[l] = m, m

详:

首先filter类似Length列,然后创建相应的Height列:

print(l)
['Object1-Length', 'Object2-Length']
print(h)
['Object1-Height', 'Object2-Height']

创建布尔掩码,表示ObjectX-Length >= 20 and ObjectX-Height >= 50的条件:

print(m)
array([[0, 1],
[1, 1],
[1, 1],
[0, 0],
[1, 1]])

将掩码分配给相应的列:

print(df)
Object1-Length  Object1-Height  Object2-Length  Object2-Height
Index                                                                
0                   0               0               1               1
1                   1               1               1               1
2                   1               1               1               1
3                   0               0               0               0
4                   1               1               1               1

你可以从numpyreshape获得帮助。 使用reshape您可以将每对"移动"到临时的 3rd 维,然后您可以拥有一个包含您要比较的"有趣"列的自然行。

在此之后,您可以还原原始数据帧形状的重塑。

import pandas as pd
import numpy as np
# example dataset
df = pd.DataFrame(np.random.randint(100, size=(8, 6)), columns = ['A-L', 'A-H', 'B-L', 'B-H', 'C-L', 'C-H'])
m, n = df.shape
data = df.values
data = data.reshape((m, 2, -1), order='F')
cond = (data[:,(0,),:] >= 20) & (data[:,(1,),:] >= 50)
new_data = np.repeat(cond, 2, axis=1)
new_data = new_data.reshape((m, -1), order='F')
new_df = pd.DataFrame(new_data, columns=df.columns)
print(df)
print(new_df)

A-L  A-H  B-L  B-H  C-L  C-H
0   36   99    0   65   44   41
1   31   52    7   33   27   80
2   39   89   57   18   72   76
3    4   13   11   38   21    9
4   72    4    9   16   78   96
5   26   79   80   53   36   81
6   81   59   93   49   39   24
7   45   49   52   54   63   70
A-L    A-H    B-L    B-H    C-L    C-H
0   True   True  False  False  False  False
1   True   True  False  False   True   True
2   True   True  False  False   True   True
3  False  False  False  False  False  False
4  False  False  False  False   True   True
5   True   True   True   True   True   True
6   True   True  False  False  False  False
7  False  False   True   True   True   True

不太优雅的方式:

r = [] 
for n in range(1, x): # where x = maximum X + 1 
len_col = f'Object{n}-Length'
height_col = f'Object{n}-Height'
# create filter mask for current object {n}
subset = df[[len_col, height_col]]
msk = (df[len_col] >= 20) & (df[height_col] >= 50)
subset.loc[msk,[len_col, height_col] = 1 
subset.loc[~msk,[len_col, height_col] = 0 
r.append(subset)

r = pd.concat(r)

删除Index列后,可以一次筛选所有列。然后groupyby每两列,如果至少False一列,则将两列都设置为False

df.set_index('Index', inplace=True)
df.ge([20,50]*(df.columns.size//2)).groupby(np.arange(df.columns.size)//2, axis=1).transform('min').astype('int')

外:

Object1-Length  Object1-Height  Object2-Length  Object2-Height
Index                                                                
0                   0               0               1               1
1                   1               1               1               1
2                   1               1               1               1
3                   0               0               0               0
4                   1               1               1               1

最新更新