Python 为什么映射可以工作,但应用会引发错误
我正在尝试使用Pandas的各种方法,我正在努力理解为什么Map、Apply和Vectoriation与返回非布尔值的函数相对可互换,但是Apply和Vectoriation有时会在应用的函数返回布尔值时失败。这个问题将集中在应用上 具体来说,我编写了非常简单的小代码来说明这一挑战:Python 为什么映射可以工作,但应用会引发错误,python,pandas,vectorization,apply,Python,Pandas,Vectorization,Apply,我正在尝试使用Pandas的各种方法,我正在努力理解为什么Map、Apply和Vectoriation与返回非布尔值的函数相对可互换,但是Apply和Vectoriation有时会在应用的函数返回布尔值时失败。这个问题将集中在应用上 具体来说,我编写了非常简单的小代码来说明这一挑战: import numpy as np import pandas as pd # make dataframe x = range(1000) df = pd.DataFrame(data = x, column
import numpy as np
import pandas as pd
# make dataframe
x = range(1000)
df = pd.DataFrame(data = x, columns = ['Number'])
# simple function to test if a number is a prime number
def is_prime(num):
if num < 2:
return False
elif num == 2:
return True
else:
for i in range(2,num):
if num % i == 0:
return False
return True
# test if every number in the dataframe is prime using Map
df['map prime'] = list(map(is_prime, df['Number']))
df.head()
我错过了什么
谢谢大家!
p、 我知道有更有效的方法来测试素数。我故意编写了一个低效的函数,这样我就可以测试应用和矢量化实际上比map快多少,但后来我遇到了这个挑战。多谢各位
所以我不再明白发生了什么:当我试图
使用apply,我会得到一个ValueError
in: df['apply prime'] = df.apply(func = is_prime, args = df['Number'], axis=1)
out: ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
df.apply(…,axis=1)
,passpd.Series(…)
即df['apply prime']=df['Number']。apply(func=is_prime)
应该可以工作
考虑到apply表面上比map和矢量化要快
更快
另外,pd.DataFrame.apply(…)
,不使用任何类型的矢量化,只使用简单的C for循环(ex.cython),所以相信map(…)
应该是渐进更快的
更新 您可能需要计算,
.apply(…)
,方法将给定的轴=x
的值传递给函数,并返回Y
,在pd.DataFrame
(多个键)的情况下,可以是任何数据类型
假设df.shape=(1000,4)
,如果我们打算沿着axis=1
,移动,即df.shape[1]
,这意味着您的apply函数将被调用1000次,每次运行它都会得到(4,)
类型pd.Series
的元素,您可以在函数本身内部使用这些键,或者只将键作为参数传递,pd.DataFrame.apply(…,args=[…])
所以我不再明白发生了什么:当我试图
使用apply,我会得到一个ValueError
in: df['apply prime'] = df.apply(func = is_prime, args = df['Number'], axis=1)
out: ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
df.apply(…,axis=1)
,passpd.Series(…)
即df['apply prime']=df['Number']。apply(func=is_prime)
应该可以工作
考虑到apply表面上比map和矢量化要快
更快
另外,pd.DataFrame.apply(…)
,不使用任何类型的矢量化,只使用简单的C for循环(ex.cython),所以相信map(…)
应该是渐进更快的
更新
您可能需要计算,.apply(…)
,方法将给定的轴=x
的值传递给函数,并返回Y
,在pd.DataFrame
(多个键)的情况下,可以是任何数据类型
假设df.shape=(1000,4)
,如果我们打算沿着axis=1
,移动,即df.shape[1]
,这意味着您的apply函数将被调用1000次,每次运行它都会得到(4,)
类型pd.Series
的元素,您可以在函数本身内部使用这些键,或者只将键作为参数传递,pd.DataFrame.apply(…,args=[…])
那确实有效,谢谢你!但现在我有第二个问题:如果我想应用一个函数,它以两个变量作为输入并返回一个布尔值(例如,如果x>y返回true),该怎么办?我如何通过这两个考试?我尝试调用df['Num1','Num2'].apply(…),但即使键是正确的,也会抛出一个键错误。当我将键作为元组传递进来时,Map起作用了。关于如何将apply与接受多个输入的函数一起使用的想法?@BLimitless,您可以参考@BLimitless的文章,还要注意,您对list(map(…)的使用实际上比apply(…axis=1)快。您可以参考我上面建议的同一篇文章中的计时比较。@4.Pi.n,我认为您的示例代码可以简化为df.apply(lambda x:func(x['a'],x['b']),axis=1)和definedef func(key1,key2)
和如果key1>key2
,则此函数可以更通用,并且可以在范围之外使用。@BLimitless,另请参见上一篇文章中的列表(映射(..)和应用(…轴=1)的比较。还有。因此,建议继续使用list(map(..)而不是apply(…axis=1)。这确实有效,谢谢!但现在我有第二个问题:如果我想应用一个函数,它以两个变量作为输入并返回一个布尔值(例如,如果x>y返回true),该怎么办?我如何通过这两个考试?我尝试调用df['Num1','Num2'].apply(…),但即使键是正确的,也会抛出一个键错误。当我将键作为元组传递进来时,Map起作用了。关于如何将apply与接受多个输入的函数一起使用的想法?@BLimitless,您可以参考@BLimitless的文章,还要注意,您对list(map(…)的使用实际上比apply(…axis=1)快。您可以参考我上面建议的同一篇文章中的计时比较。@4.Pi.n,我认为您的示例代码可以简化为df.apply(lambda x:func(x['a'],x['b']),axis=1)和definedef func(key1,key2)
和如果key1>key2
,则此函数可以更通用,并且可以在范围之外使用。@BLimitless,另请参见上一篇文章中的列表(映射(..)和应用(…轴=1)的比较。还有。因此,建议继续使用list(map(..)而不是apply(…axis=1)。
def func(x, key1, key2):
# print(x.shape)
if x[key1] > x[key2]:
return True
return False
df.apply(func, axis=1, args=['a', 'b'])