pandas 将函数应用于行:只能将整数标量数组转换为标量索引
pandas apply function to row: only integer scalar arrays can be converted to a scalar index
我有一个df,代码在这里:
df4s = """
contract RB BeginDate ValIssueDate EndDate Valindex0
2 A00118 46 19850100 19880901 99999999 50
3 A00118 47 19000100 19880901 19831231 47
5 A00118 47 19850100 19880901 99999999 50
6 A00253 48 19000100 19820101 19811231 47
7 A00253 48 19820100 19820101 19841299 47
8 A00253 48 19850100 19820101 99999999 50
9 A00253 50 19000100 19820101 19781231 47
10 A00253 50 19790100 19820101 19841299 47
11 A00253 50 19850100 19820101 99999999 50
"""
df4 = pd.read_csv(StringIO(df4s.strip()), sep='\s+',
dtype={"RB": str, "BeginDate": int, "EndDate": int,'ValIssueDate':int,'Valindex0':int})
输出:
contract RB BeginDate ValIssueDate EndDate Valindex0
2 A00118 46 19850100 19880901 99999999 50
3 A00118 47 19000100 19880901 19831231 47
5 A00118 47 19850100 19880901 99999999 50
6 A00253 48 19000100 19820101 19811231 47
7 A00253 48 19820100 19820101 19841299 47
8 A00253 48 19850100 19820101 99999999 50
9 A00253 50 19000100 19820101 19781231 47
10 A00253 50 19790100 19820101 19841299 47
11 A00253 50 19850100 19820101 99999999 50
我想添加一个新列:
df4['n']
基于现有列 df4['RB'] 之一,如下所示:
def test(RB):
n=1
for i in range(RB,50):
n+=1
return n
df4['n']=test(df4['RB'].values)
但是我使用这种 numpy 方式收到错误消息:
<ipython-input-18-3831e3b8068d> in test(RB)
17 def test(RB):
18 n=1
---> 19 for i in range(RB,50):
20 n+=1
21 return n
TypeError: only integer scalar arrays can be converted to a scalar index
因为如果我在测试函数中打印 RB,该值不是单个值,而是一个数组:
['46' '47' '47' '48' '48' '48' '50' '50' '50']
但如果我使用较慢的方法,它会起作用:
def test(row):
n=1
for i in range(int(row['RB']),50):
n+=1
df4['n'] = df4.apply(lambda row: test(row), axis=1)
正确的输出是:
contract RB BeginDate ValIssueDate EndDate Valindex0 n
2 A00118 46 19850100 19880901 99999999 50 5
3 A00118 47 19000100 19880901 19831231 47 4
5 A00118 47 19850100 19880901 99999999 50 4
6 A00253 48 19000100 19820101 19811231 47 3
7 A00253 48 19820100 19820101 19841299 47 3
8 A00253 48 19850100 19820101 99999999 50 3
9 A00253 50 19000100 19820101 19781231 47 1
10 A00253 50 19790100 19820101 19841299 47 1
11 A00253 50 19850100 19820101 99999999 50 1
我想用更快的方法来做到这一点,而不是更慢的方法,有什么方法可以修复第一种方法吗?目标是在方法 1 中使用循环。
这只是一个示例,我的确切函数非常复杂,看起来像:
def getnpx(df, age, interest):
val = 1
initval = 1
print(age.astype(int))
for i in np.arange(age.astype(int), 136):
val = val * df[str(i)].values
intval = val / (1 + interest) ** (i + 1 - age)
initval = initval + intval
return initval
你试图以复杂的方式做的只是一个减法。
试试看:
df['n'] = 51 - df['RB'].astype(int)
我终于找到方法了:
vfunc=np.vectorize(test)
df4['n']=vfunc(df4['RB'].values)
我有一个df,代码在这里:
df4s = """
contract RB BeginDate ValIssueDate EndDate Valindex0
2 A00118 46 19850100 19880901 99999999 50
3 A00118 47 19000100 19880901 19831231 47
5 A00118 47 19850100 19880901 99999999 50
6 A00253 48 19000100 19820101 19811231 47
7 A00253 48 19820100 19820101 19841299 47
8 A00253 48 19850100 19820101 99999999 50
9 A00253 50 19000100 19820101 19781231 47
10 A00253 50 19790100 19820101 19841299 47
11 A00253 50 19850100 19820101 99999999 50
"""
df4 = pd.read_csv(StringIO(df4s.strip()), sep='\s+',
dtype={"RB": str, "BeginDate": int, "EndDate": int,'ValIssueDate':int,'Valindex0':int})
输出:
contract RB BeginDate ValIssueDate EndDate Valindex0
2 A00118 46 19850100 19880901 99999999 50
3 A00118 47 19000100 19880901 19831231 47
5 A00118 47 19850100 19880901 99999999 50
6 A00253 48 19000100 19820101 19811231 47
7 A00253 48 19820100 19820101 19841299 47
8 A00253 48 19850100 19820101 99999999 50
9 A00253 50 19000100 19820101 19781231 47
10 A00253 50 19790100 19820101 19841299 47
11 A00253 50 19850100 19820101 99999999 50
我想添加一个新列:
df4['n']
基于现有列 df4['RB'] 之一,如下所示:
def test(RB):
n=1
for i in range(RB,50):
n+=1
return n
df4['n']=test(df4['RB'].values)
但是我使用这种 numpy 方式收到错误消息:
<ipython-input-18-3831e3b8068d> in test(RB)
17 def test(RB):
18 n=1
---> 19 for i in range(RB,50):
20 n+=1
21 return n
TypeError: only integer scalar arrays can be converted to a scalar index
因为如果我在测试函数中打印 RB,该值不是单个值,而是一个数组:
['46' '47' '47' '48' '48' '48' '50' '50' '50']
但如果我使用较慢的方法,它会起作用:
def test(row):
n=1
for i in range(int(row['RB']),50):
n+=1
df4['n'] = df4.apply(lambda row: test(row), axis=1)
正确的输出是:
contract RB BeginDate ValIssueDate EndDate Valindex0 n
2 A00118 46 19850100 19880901 99999999 50 5
3 A00118 47 19000100 19880901 19831231 47 4
5 A00118 47 19850100 19880901 99999999 50 4
6 A00253 48 19000100 19820101 19811231 47 3
7 A00253 48 19820100 19820101 19841299 47 3
8 A00253 48 19850100 19820101 99999999 50 3
9 A00253 50 19000100 19820101 19781231 47 1
10 A00253 50 19790100 19820101 19841299 47 1
11 A00253 50 19850100 19820101 99999999 50 1
我想用更快的方法来做到这一点,而不是更慢的方法,有什么方法可以修复第一种方法吗?目标是在方法 1 中使用循环。
这只是一个示例,我的确切函数非常复杂,看起来像:
def getnpx(df, age, interest):
val = 1
initval = 1
print(age.astype(int))
for i in np.arange(age.astype(int), 136):
val = val * df[str(i)].values
intval = val / (1 + interest) ** (i + 1 - age)
initval = initval + intval
return initval
你试图以复杂的方式做的只是一个减法。
试试看:
df['n'] = 51 - df['RB'].astype(int)
我终于找到方法了:
vfunc=np.vectorize(test)
df4['n']=vfunc(df4['RB'].values)