Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 矢量化自定义函数未按预期在中工作_Python_Python 3.x_Pandas_Data Science_Vectorization - Fatal编程技术网

Python 矢量化自定义函数未按预期在中工作

Python 矢量化自定义函数未按预期在中工作,python,python-3.x,pandas,data-science,vectorization,Python,Python 3.x,Pandas,Data Science,Vectorization,以pycon talk为来源 def clean_string(item): if type(item)==type(1): return item else: return np.nan dataframe对象有一列包含数字和字符串数据,我想将字符串更改为np.nan 同时保持数字数据不变 这种方法很有效 df['Energy Supply'].apply(clean_string) 但是当我尝试使用矢量化时,所有列项目的值都变为np.na

以pycon talk为来源

def clean_string(item):
    if type(item)==type(1):
        return item
    else:
        return np.nan

dataframe对象有一列包含数字和字符串数据,我想将字符串更改为
np.nan
同时保持数字数据不变

这种方法很有效

df['Energy Supply'].apply(clean_string)
但是当我尝试使用矢量化时,所有列项目的值都变为
np.nan

df['Energy Supply'] = clean_string(df['Energy Supply'])  # vectorisation
但是上面的方法是将所有项转换为
np.nan
。我相信这是因为
type(item)
clean_string
函数中是
pd.Series
类型

有没有办法克服这个问题


PS:pandas中的矢量化操作并不总是可能的,我是pandas的初学者。我不知道有一种内置的矢量化方法来获取系列中元素的类型,因此您的
.apply()
解决方案可能是最好的方法

在第二种情况下,代码不起作用的原因是将整个序列传递给
clean_string()
函数。它将序列的类型与
type(1)
进行比较,后者为
False
,然后返回一个值
np.nan
。Pandas在将该值分配回df时会自动广播该值,因此会得到一列
NaN
。为了避免这种情况,您必须在
clean_string()
函数的系列中循环所有元素

出于好奇,我尝试了其他几种方法,看看它们是否比您的版本更快。为了测试,我创建了10000和100000元素
pd.Series
,其中交替使用整数和字符串值:

将numpy导入为np
作为pd进口熊猫
s=pd.系列(如果i%2==0,则i为范围(10000)内的i的其他str(i))
s2=pd.系列(如果i%2==0,则i为范围(100000)内的i的其他str(i))
这些测试是使用pandas 1.0.3和python 3.8完成的

使用
clean_string()
[]中的
:%timeit s.apply(清除字符串)
每个回路3.75 ms±14.4µs(7次运行的平均值±标准偏差,每个100个回路)
在[]中:%timeit s2.apply(清除字符串)
每个回路39.5 ms±301µs(7次运行的平均值±标准偏差,每个10个回路)
Series.str
方法 测试字符串与非字符串的另一种方法是在序列上使用内置的
.str
函数,例如,如果应用
.str.len()
,它将为序列中的任何非字符串返回
NaN
。这些在熊猫文档中甚至被称为“”,因此它们可能会更有效

[]中的
:%timeit s.mask(s.str.len()>0)
每个回路6 ms±39.2µs(7次运行的平均值±标准偏差,每个100个回路)
在[]中:%timeit s2.mask(s2.str.len()>0)
每个回路56.8 ms±142µs(7次运行的平均值±标准偏差,每个10个回路)
不幸的是,这种方法比
.apply()
慢。尽管被“矢量化”,但这看起来并不是一个更好的方法。它与
clean_string()
的逻辑也不完全相同,因为它测试的是字符串元素,而不是整数元素

类型
直接应用于序列 基于,我决定使用
.apply()
type
进行测试,以获得每个元素的类型。一旦我们知道了类型,比较
int
,并使用
.mask()
方法将任何非整数转换为
NaN

[]中的
:%timeit s.mask(s.apply(type)!=int)
每个回路1.88 ms±4.7µs(7次运行的平均值±标准偏差,每个1000个回路)
在[]中:%timeit s2.mask(s2.apply(type)!=int)
每个回路15.2 ms±32.8µs(7次运行的平均值±标准偏差,每个100个回路)
这是我发现的最快的方法