Python 可以有条件地选择多个列
假设我有一个数据帧:Python 可以有条件地选择多个列,python,pandas,conditional,extract,multiple-columns,Python,Pandas,Conditional,Extract,Multiple Columns,假设我有一个数据帧: C1 V1 C2 V2 Cond 1 2 3 4 X 5 6 7 8 Y 9 10 11 12 X 语句应该返回:如果Cond==X,选择C1和C2,否则选择C2和V2 输出数据帧类似于: C V 1 2 7 8 9 10 **编辑:再添加一个要求:列的数量可以更改,但遵循某种命名模式。在这种情况下,选择所有包含“1”的列,否则选择包含“2”的列。我认为硬编码的解决方案可能不起作用 dropCond关注我从中选择的值 重塑nump
C1 V1 C2 V2 Cond
1 2 3 4 X
5 6 7 8 Y
9 10 11 12 X
语句应该返回:如果Cond==X,选择C1和C2,否则选择C2和V2
输出数据帧类似于:
C V
1 2
7 8
9 10
**编辑:再添加一个要求:列的数量可以更改,但遵循某种命名模式。在这种情况下,选择所有包含“1”的列,否则选择包含“2”的列。我认为硬编码的解决方案可能不起作用 drop
关注我从中选择的值Cond
numpy数组,以便使用布尔值进行区分重塑
- 用
索引第一维度,每行一次np.arange(len(df))
- 用
索引第二维度<代码>0表示等于df.Cond.ne('X').mul(1)
X
- 构造最终数据帧
drop
关注我从中选择的值Cond
numpy数组,以便使用布尔值进行区分重塑
- 用
索引第一维度,每行一次np.arange(len(df))
- 用
索引第二维度<代码>0表示等于df.Cond.ne('X').mul(1)
X
- 构造最终数据帧
您可以尝试使用与中类似的方法 首先,定义两个函数:
def cond(row):
return row['Cond'] == 'X'
def helper(row, col_if, col_ifnot):
return row[col_if] if cond(row) else row[col_ifnot]
然后,假设您的数据帧被称为df
df_new = pd.DataFrame(index=df.index)
for col in ['C', 'V']:
col_1 = col + '1'
col_2 = col + '2'
df_new[col] = df.apply(lambda row: helper(row, col_1, col_2), axis=1)
请记住,这种方法对于大型数据帧可能比较慢,因为
apply
没有利用矢量化。但是,它甚至可以用于任意列名(只需将['C','V']
替换为实际的列名即可)。您可以尝试使用与中类似的方法
首先,定义两个函数:
def cond(row):
return row['Cond'] == 'X'
def helper(row, col_if, col_ifnot):
return row[col_if] if cond(row) else row[col_ifnot]
然后,假设您的数据帧被称为df
df_new = pd.DataFrame(index=df.index)
for col in ['C', 'V']:
col_1 = col + '1'
col_2 = col + '2'
df_new[col] = df.apply(lambda row: helper(row, col_1, col_2), axis=1)
请记住,这种方法对于大型数据帧可能比较慢,因为apply
没有利用矢量化。但是,它甚至可以用于任意列名(只需将['C','V']
替换为实际的列名即可)。如果行的顺序不重要,则可以使用
ndf1 = df.loc[df['Cond'] == 'X', ['C1','V1']]
ndf2 = df.loc[df['Cond'] == 'Y', ['C2','V2']]
ndf1.columns = ['C','V']
ndf2.columns = ['C','V']
result = ndf1.append(ndf2).reset_index(drop=True)
print(result)
C V
0 1 2
1 9 10
2 7 8
如果行的顺序不重要,可以使用和
ndf1 = df.loc[df['Cond'] == 'X', ['C1','V1']]
ndf2 = df.loc[df['Cond'] == 'Y', ['C2','V2']]
ndf1.columns = ['C','V']
ndf2.columns = ['C','V']
result = ndf1.append(ndf2).reset_index(drop=True)
print(result)
C V
0 1 2
1 9 10
2 7 8
另一个带有
数据帧的选项。其中()
:
另一个带有
数据帧的选项。其中()
:
我尝试使用和创建更通用的解决方案,对于新列名,请使用:
我尝试使用和创建更通用的解决方案,对于新列名,请使用:
indexer={'X':['C1','V1'],'Y':['C2','V2']}的可能重复项;indexer.items()中k,v的pd.concat([pd.DataFrame(df.loc[df.Cond==k,v]。值,列=['C','v'])
是这样做的一种方法,但它不保留行的顺序。indexer={'X':['C1',V1'],'Y':['C2',V2'];index.items()]中k,v的pd.concat([pd.DataFrame(df.loc[df.Cond==k,v]。值,列=['C','v'])
是一种方法,但它不保留行的顺序。
#np.where need same shape of mask as df1 and df2
mask = pd.concat([df.Cond == 'X']*len(df1.columns), axis=1)
print (mask)
Cond Cond
0 True True
1 False False
2 True True
cols = df1.columns.str.extract('([A-Za-z])', expand=False)
print (cols)
Index(['C', 'V'], dtype='object')
print (np.where(mask, df1,df2))
Index(['C', 'V'], dtype='object')
[[ 1 2]
[ 7 8]
[ 9 10]]
print (pd.DataFrame(np.where(mask, df1, df2), index=df.index, columns=cols))
C V
0 1 2
1 7 8
2 9 10