我正在尝试使用函数创建一组新列,这些新列将从数据框中的现有列派生。这是产生错误的示例代码,我想知道是否有比循环更好的更有效的方法
import numpy as np
import pandas as pd
dates = pd.date_range('1/1/2000', periods=100, freq='M')
long_df = pd.DataFrame(np.random.randn(100, 4),index=dates, columns=['Colorado', 'Texas', 'New York', 'Ohio'])
mylist=['Colorado', 'Texas', 'New York', 'Ohio']
def trnsfrm_1_10 (a, b):
b = (a-np.min(a))/(np.max(a)-np.min(a))*9+1
return b
for a in mylist:
b=a+"_T"
long_df[b] = long_df.apply(lambda row: trnsfrm_1_10(row[a], row[b]), axis=1)
为澄清上述问题,以下是DataFrame的示例,该示例具有输入列(科罗拉多州,德克萨斯州,纽约)和输出变量(T_Colorado,T_Texas,T_New York)。假设如果对于每个输入变量,下面是每列的最小值和最大值,则通过对每列应用方程式:b =(a-min)/(max-min)* 9 + 1,输出变量为T_Colorado T_Texas T_New约克我只需要基于5行在excel中模拟此过程,但是将最小值和最大值作为函数的一部分进行计算将非常有用,因为我在真实数据中会有很多行。我是Python和Pandas的新手,非常感谢您的帮助。
这些是最小和最大示例
Colorado Texas New York
min 0.03 -1.26 -1.04
max 1.17 0.37 0.86
这是DataFrame的示例
Index Colorado Texas New York T_Colorado T_Texas T_New York
1/31/2000 0.03 0.37 0.09 1.00 10.00 6.35
2/29/2000 0.4 0.26 -1.04 3.92 9.39 1.00
3/31/2000 0.35 -0.06 -0.75 3.53 7.63 2.37
4/30/2000 1.17 -1.26 -0.61 10.00 1.00 3.04
5/31/2000 0.46 -0.79 0.86 4.39 3.60 10.00
答案 0 :(得分:2)
IIUC,您应该利用广播
matrix(unlist(read.table("/Users/Users/Desktop/Test")),
ncol = 3, byrow = TRUE)-> Matrix
然后long_df2= (long_df - long_df.min())/(long_df.max() - long_df.min()) * 9 + 1
concat
答案 1 :(得分:1)
在您的代码中,错误是当您定义trnsfrm_1_10
时,b
是一个参数,而实际上只是您的输出。它不应该是参数,尤其是它是您要在循环for
期间创建的新列中的值时。因此代码将类似于:
def trnsfrm_1_10 (a):
b = (a-np.min(a))/(np.max(a)-np.min(a))*9+1
return b
for a in mylist:
b=a+"_T"
long_df[b] = long_df.apply(lambda row: trnsfrm_1_10(row[a]), axis=1)
另一件事是您在np.min(a)
中计算trnsfrm_1_10
,实际上等于a
(与max
相同),因为您apply
行对因此a
是您所在行和列中的唯一值。我假设您的意思是更多np.min(long_df['a'])
,也可以写成long_df[a].min()
如果我理解得很清楚,您实际上要执行的操作是:
dates = pd.date_range('1/1/2000', periods=100, freq='M')
long_df = pd.DataFrame(np.random.randn(100, 4),index=dates,
columns=['Colorado', 'Texas', 'New York', 'Ohio'])
mylist=['Colorado', 'Texas', 'New York', 'Ohio']
for a in mylist:
long_df[a+"_T"] = (long_df[a]-long_df[a].min())/(long_df[a].max()-long_df[a].min())*9+1
然后给予:
long_df.head()
Out[29]:
Colorado Texas New York Ohio Colorado_T Texas_T \
2000-01-31 -0.762666 1.413276 0.857333 0.648960 3.192754 7.768111
2000-02-29 0.148023 0.304971 1.954966 0.656787 4.676018 6.082177
2000-03-31 0.531195 1.283100 0.070963 1.098968 5.300102 7.570091
2000-04-30 -0.385679 0.425382 1.330285 0.496238 3.806763 6.265344
2000-05-31 -0.047057 -0.362419 -2.276546 0.297990 4.358285 5.066955
New York_T Ohio_T
2000-01-31 6.390972 5.659870
2000-02-29 8.242445 5.676254
2000-03-31 5.064533 6.601876
2000-04-30 7.188740 5.340175
2000-05-31 1.104787 4.925180
其中,带有_T
的列中的所有值都是从相应列中计算得出的。
最终不要在列上使用for
循环,您可以这样做:
long_df_T =(((long_df -long_df.min(axis=0))/(long_df.max(axis=0) -long_df.min(axis=0))*9 +1)
.add_suffix('_T'))
立即创建一个包含所有带有_T
的列的数据框。然后很少有选项可以将它们添加到long_df
中,一种方法是使用join
:
long_df = long_df.join(long_df_T)