我正在学习python,所以如果我的问题太基本了,请原谅。实际上,我需要根据不同条件在熊猫数据框上创建多个列。我可以在R中使用data.table做到这一点。我在代码下方粘贴了R-
的示例数据library(data.table)
cr=4
phi=1.85
colA <- sample(1.05:20.00,1000,replace=T)
colB <- sample(1.05:20.00,1000,replace=T)
colC <- sample(1.05:20.00,1000,replace=T)
SALES <- sample(1.05:20.00,1000,replace=T)
colD <- sample(1.05:20.00,1000,replace=T)
VALUE <- sample(1.05:20.00,1000,replace=T)
df <- as.data.table(data.frame(colA,colB,colC,colD,SALES,VALUE))
df <- df[, c("colB_exp","colC_exp", "Unit_exp","Value_exp")
:= list (ifelse(!is.na(colA),pmin(colB * colA,(cr-1)*1/phi^2+cr*SALES * colA),0),
ifelse(!is.na(colA),pmin(colC * colA,(cr-1)*1/phi^2+cr*SALES * colD * colA),0),
ifelse(!is.na(colA),SALES * colA,0),
ifelse(!is.na(colA),VALUE * colA,0)
)]
因此,如您所见,在此示例中我需要创建4列(实际上,还需要创建7个具有不同条件的列,但出于示例目的,我只考虑了4个)
现在,我正在尝试在Python中执行相同的操作,但无法获得如何执行此操作。另外,我不确定我是否以有效的方式执行此操作,因为似乎无法为要创建的每个新列进行过多的编码。 以下是我在Python中尝试的示例数据和代码-
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.uniform(0,100,size=(100, 6)), columns=list(['colA','colB','colC','colD','SALES','VALUE']))
cr=4
phi=1.85
def colB_exp(row):
return min(df['colB'] * df['colA'],(cr-1)*1/phi^2+cr* df['SALES'] * df['colA'])
df['colB_exp'] = df.apply(lambda row:colB_exp(row) if df['colA'].notnull().all() else 0,axis = 1)
但是我得到了错误,因为 TypeError:无法对类型为[bool]的dtyped [float64]数组和标量执行'rxor'
当我检查df的数据类型时,所有列都是float64,实际上在我的主数据中就是这种情况。
不确定是什么问题,我该如何解决。
我是否必须为每个列条件创建函数?有更好的方法吗?
谢谢!!
答案 0 :(得分:1)
您不能使用min直接比较2列。它需要在元素级别应用。 您能检查一下这种故障是否起作用。
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.uniform(0,100,size=(100, 6)), columns=list(['colA','colB','colC','colD','SALES','VALUE']))
cr = 4
phi = 1.85
def colB_exp():
A = df['colB']* df['colA']
B = (cr-1)*1/phi**2+cr* df['SALES'] * df['colA']
return [min(a,b) for a,b in zip(A, B)]
df['colB_exp'] = colB_exp()
df['colB_exp'][df['colA'].isna()] = 0
df
答案 1 :(得分:1)
如果避免使用apply
,它将更快,您可以使用np.where
:
>>> df = pd.DataFrame(np.random.uniform(0,100,size=(100, 6)),
columns=list(['colA','colB','colC','colD','SALES','VALUE']))
>>> cr=4
>>> phi=1.85
>>> df['colB_exp'] = np.where(
df['colA'].notnull(),
pd.concat([
df['colB'] * df['colA'],
(cr-1)*1/phi**2+cr* df['SALES'] * df['colA']
],axis=1).min(1), 0
)
>>> df
colA colB colC ... SALES VALUE colB_exp
0 22.549300 64.278204 31.008298 ... 42.493048 59.603801 1449.428473
1 69.699479 69.173731 98.060696 ... 45.343364 40.046332 4821.373010
2 49.174025 81.000527 62.022084 ... 49.619752 18.370626 3983.121926
3 88.094696 33.193363 59.168448 ... 72.243254 8.378294 2924.159181
4 57.385150 14.326797 92.865076 ... 33.228036 55.651635 822.145427
.. ... ... ... ... ... ... ...
95 94.641142 39.684918 59.073406 ... 66.350751 38.040689 3755.825953
96 7.527524 10.376946 56.894015 ... 8.575608 71.710560 78.112711
97 12.258327 17.919200 97.053017 ... 22.476308 79.233166 219.659423
98 76.264761 60.973407 97.328900 ... 57.116251 29.756769 4650.122372
99 30.687590 77.486464 7.277809 ... 97.560641 4.835084 2377.872852
[100 rows x 7 columns]
您可以进一步查看df.assign
,一次添加多个列。