我的问题是如何简化以下代码。在我的实际数据中,我必须添加540列,但我想有更好的方法,特别是对于生成列。甚至可能是单独的数据帧?
下面你会看到我需要一列的test-df。需要生成'bin_X_0'到'bin_X_9',然后生成几个,即bin_Y_0,bin_Z_0等到9。
N = 10000
J = [2012,2013,2014]
K = ['A','B','C','D','E','F','G','H']
L = ['h', 'd', 'a']
S = ['AR1','PO1','RU1']
np.random.seed(0)
df = pd.DataFrame(
{'Y':np.random.uniform(1,10,N),
'X':np.random.uniform(1,10,N),
'Z':np.random.uniform(1,10,N),
'J':np.random.choice(J,N),
'S':np.random.choice(S,N),
'R':np.random.choice(L,N)
})
df['bins_X'] = df.groupby('S').X.apply(pd.qcut, q=10, labels=np.arange(10))
df['bin_X_0'] = np.where((df['bins_X'] ==0) & (df['R'] =='a'), (df['X']*2)-2,
np.where((df['bins_X'] ==0) & (df['R'] !='a'), -2, 0))
df.head()
答案 0 :(得分:1)
通过使用当前迭代和format
函数生成新列,可以使用双for循环实现此目的。以下代码应该这样做:
for a in ["X", "Y", "Z"]:
for num in list(range(0, 10)):
df['bins_{}'.format(a)] = df.groupby('S')["{}".format(a)].apply(pd.qcut, q=10, labels=np.arange(10))
df['bin_{}_{}'.format(a, num)] = np.where((df['bins_{}'.format(a)] == num) & (df['R'] == 'a'),
(df['{}'.format(a)] * 2) - 2,
np.where((df['bins_{}'.format(a)] == num) & (df['R'] != 'a'), -2, 0))
我希望很清楚,当前的数字和字母如何动态地获取适当的数据并在每个嵌套循环中生成两个新列。上面的代码产生了这个数据帧,我相信你正在寻找它:
J R S X Y Z bins_X bin_X_0 bin_X_1 \
0 2014 d PO1 7.734412 5.939322 4.529557 7 0.000000 0.0
1 2014 h AR1 2.621824 7.436704 1.370409 1 0.000000 -2.0
2 2013 h PO1 4.501208 6.424870 9.309705 4 0.000000 0.0
3 2012 a RU1 1.338402 5.903949 4.656115 0 0.676803 0.0
4 2012 d RU1 1.106090 4.812893 9.498540 0 -2.000000 0.0
bin_X_2 ... bin_Z_0 bin_Z_1 bin_Z_2 bin_Z_3 bin_Z_4 bin_Z_5 \
0 0.0 ... 0.0 0.0 0.0 -2.0 0.00000 0.0
1 0.0 ... -2.0 0.0 0.0 0.0 0.00000 0.0
2 0.0 ... 0.0 0.0 0.0 0.0 0.00000 0.0
3 0.0 ... 0.0 0.0 0.0 0.0 7.31223 0.0
4 0.0 ... 0.0 0.0 0.0 0.0 0.00000 0.0
bin_Z_6 bin_Z_7 bin_Z_8 bin_Z_9
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 -2.0
3 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 -2.0
我希望你明白这一点。
答案 1 :(得分:0)
如果新列与DataFrame中已有的数据相关,则添加新列的最佳方法是使用pd.concat或pd.merge。
您可以在http://pandas.pydata.org/pandas-docs/stable/merging.html
上详细了解相关信息