我正在尝试根据其他几个值的值创建一个有条件的新变量。我在这里写,因为我已经尝试将它写成R中的嵌套ifelse()语句,但它有太多嵌套的ifelse,所以它抛出了一个错误,我认为应该有一种更简单的方法来解决这个问题在Python中。
我有一个大致相似的数据框(称为df)(虽然实际上它有更大的月/年变量),我已经读作了一个pandas DataFrame:
{
"TypedProperty": 5,
"UntypedProperty": {
"$type": "Question38777588.TypeWrapper`1[[System.Guid, mscorlib]], Tile",
"Value": "e2983c59-5ec4-41cc-b3fe-34d9d0a97f22"
}
}
我正在尝试创建一个依赖于所有这些变量的值的新变量,但是来自“早期”变量的值需要有先例,所以if / elif / else条件需要这样的东西:
ID Sept_2015 Oct_2015 Nov_2015 Dec_2015 Jan_2016 Feb_2016 Mar_2016 \
0 1 0 0 0 0 1 1 1
1 2 0 0 0 0 0 0 0
2 3 0 0 0 0 1 1 1
3 4 0 0 0 0 0 0 0
4 5 1 1 1 1 1 1 1
grad_time
0 240
1 218
2 236
3 0
4 206
基于此,我希望它返回一个看起来像这样的新变量:
if df['Sept_2015'] > 0 & df['grad_time'] <= 236:
return 236
elif df['Oct_2015'] > 0 & df['grad_time'] <= 237:
return 237
elif df['Nov_2015'] > 0 & df['grad_time'] <= 238:
return 238
elif df['Dec_2015'] > 0 & df['grad_time'] <= 239:
return 239
elif df['Jan_2016'] > 0 & df['grad_time'] <= 240:
return 240
elif df['Feb_2016'] > 0 & df['grad_time'] <= 241:
return 241
elif df['Mar_2016'] > 0 & df['grad_time'] <= 242:
return 242
else:
return 0
我尝试过编写这样的函数:
trisk
0 240
1 0
2 240
3 0
4 236
并将其映射到数据框以创建新变量,如下所示:
def test_func(df):
""" Test Function for generating new value"""
if df['Sept_2015'] > 0 & df['grad_time'] <= 236:
return 236
elif df['Oct_2015'] > 0 & df['grad_time'] <= 237:
return 237
...
else:
return 0
但是,当我运行它时,我得到以下TypeError
new_df = pd.DataFrame(map(test_func, df))
所以我可以看到它不希望这里的列名。但我已经尝试了许多其他方法,但无法让它发挥作用。另外,我理解这可能不是写这个(映射函数)的最好方法,所以我愿意尝试解决生成trisk变量问题的新方法。如果我没有提供任何东西,请提前致谢并道歉。
答案 0 :(得分:2)
df = pd.DataFrame([[0, 0, 0, 0, 1, 1, 1, 240],
[0, 0, 0, 0, 0, 0, 0, 218],
[0, 0, 0, 0, 1, 1, 1, 236],
[0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 206]],
pd.Index(range(1, 6), name='ID'),
['Sept_2015', 'Oct_2015', 'Nov_2015', 'Dec_2015',
'Jan_2016', 'Feb_2016', 'Mar_2016', 'grad_time'])
我主要使用numpy
a = np.array([236, 237, 238, 239, 240, 241, 242])
b = df.values[:, :-1]
g = df.values[:, -1][:, None] <= a
a[(b & g).argmax(1)] * (b & g).any(1)
将其分配给新列
df['trisk'] = a[(b != 0).argmax(1)] * (b != 0).any(1)
df
答案 1 :(得分:2)
无需简化您的逻辑(@piRSquared进入):您可以通过向数据框发出test_func
将.apply(test_func, axis=1)
应用于行。
import io
import pandas as pd
data = io.StringIO('''\
ID Sept_2015 Oct_2015 Nov_2015 Dec_2015 Jan_2016 Feb_2016 Mar_2016 grad_time
0 1 0 0 0 0 1 1 1 240
1 2 0 0 0 0 0 0 0 218
2 3 0 0 0 0 1 1 1 236
3 4 0 0 0 0 0 0 0 0
4 5 1 1 1 1 1 1 1 206
''')
df = pd.read_csv(data, delim_whitespace=True)
def test_func(df):
""" Test Function for generating new value"""
if df['Sept_2015'] > 0 & df['grad_time'] <= 236:
return 236
elif df['Oct_2015'] > 0 & df['grad_time'] <= 237:
return 237
elif df['Nov_2015'] > 0 & df['grad_time'] <= 238:
return 238
elif df['Dec_2015'] > 0 & df['grad_time'] <= 239:
return 239
elif df['Jan_2016'] > 0 & df['grad_time'] <= 240:
return 240
elif df['Feb_2016'] > 0 & df['grad_time'] <= 241:
return 241
elif df['Mar_2016'] > 0 & df['grad_time'] <= 242:
return 242
else:
return 0
trisk = df.apply(test_func, axis=1)
trick.name = 'trisk'
print(trisk)
输出:
0 240
1 0
2 240
3 0
4 236
Name: trisk, dtype: int64