问题描述
我明确地说:我想在假设数据框中生成一个新列,该列可能具有不同数量的布尔值列。这些“布尔列”是根据其他参数预先创建的,它们可以是3、4或10(例如k1,k2,k3,k4等)。 我知道我可以设置这样的代码:
def get_set(row):
if row['k1'] == True:
return 'k1'
if row['k2'] == True:
return 'k2'
if row['k3'] == True:
return 'k3'
if row['k4'] == True:
return 'k4'
,然后创建新列:
data_frame['Set number'] = data_frame.apply(get_set,axis=1)
但是,如果我需要自动执行该过程怎么办?我的意思是,我希望编写与列(集合)数无关的东西,并且每次通过输入给出集合时都可以工作。 我已经尝试过了:
def get_set2(row):
discontinuity_set = []
while True:
n = 'k' + (input('set index: '))
if n == 'kstop':
return discontinuity_set
break
else:
discontinuity_set.append(n)
if row[discontinuity_set] == True:
return discontinuity_set
试图生成一个列表,从中可以从.apply绘制以创建新列,但出现此错误消息:
TypeError: 'DataFrame' object is not callable
还有for循环,效果也不佳。
有人知道如何做到这一点吗?我非常感谢任何帮助。谢谢
解决方法
这有帮助吗?
df['res'] = False
strings= ['k4','k3','k2','k1']
for key in strings:
df[df[key ] == true]['res'] = key
,
您可以使用列表推导来过滤布尔列名,只要它们具有使它们与其他列唯一的模式即可。然后只需在使用DataFrame.apply
时将其传递给您的函数即可(额外的关键字参数将传递给该函数以进行应用)。
def get_set(row,names):
for name in names:
if row[name] == True:
return name
boolean_columns = [col for col in data_frame.columns if col.startswith('k')]
data_frame['Set number'] = data_frame.apply(get_set,axis=1,names=boolean_columns)
,
或者:
import numpy as np
import pandas as pd
d = pd.DataFrame(np.random.choice([True,False],(4,5)),columns = ['k' + str(x) for x in range(5)])
d['something'] = list('ASDE')
def get_set(*args):
for row in args:
for i,x in enumerate(row):
if x :
return i
d['Set number'] = [d.columns[x]\
for x in d\
.reindex(sorted(d.columns),axis = 1)\
.loc[:,d.columns.str.startswith('k')]\
.apply(get_set,axis = 1)]
print(d)
# k0 k1 k2 k3 k4 something Set number
# 0 False False True False False A k2
# 1 False False True True False S k2
# 2 True True False False False D k0
# 3 True True False False False E k0