Python pandas数据帧上的numpy.where方法的结果是在完整数组上计算的还是在过滤数组上计算的?
我想在pandas数据帧上使用Python pandas数据帧上的numpy.where方法的结果是在完整数组上计算的还是在过滤数组上计算的?,python,arrays,pandas,numpy,Python,Arrays,Pandas,Numpy,我想在pandas数据帧上使用numpyp.where来检查列中是否存在某个字符串。如果字符串存在,则应用拆分函数并获取第二个列表元素(如果不只是获取第一个字符)。但是,以下代码不起作用,它会抛出一个索引器:列表索引超出范围,因为第一个条目不包含下划线: import pandas as pd import numpy as np df = pd.DataFrame({'A':['a','a_1','b_','b_2_3']}) df["B"] = np.where(df.A.str.conta
numpyp.where
来检查列中是否存在某个字符串。如果字符串存在,则应用拆分函数并获取第二个列表元素(如果不只是获取第一个字符)。但是,以下代码不起作用,它会抛出一个索引器:列表索引超出范围
,因为第一个条目不包含下划线:
import pandas as pd
import numpy as np
df = pd.DataFrame({'A':['a','a_1','b_','b_2_3']})
df["B"] = np.where(df.A.str.contains('_'),df.A.apply(lambda x: x.split('_')[1]),df.A.str[0])
仅调用np。其中
返回条件为真的索引数组,因此我的印象是,split
-命令将仅用于该数据子集:
np.where(df.A.str.contains('_'))
Out[14]: (array([1, 2, 3], dtype=int64),)
但是显然,split
-命令用于整个未过滤数组,这对我来说似乎很奇怪,因为这可能是大量不必要的操作,会减慢计算速度
我不是在要求一个替代的解决方案,想出来并不难
我只是想知道这是预期结果还是pandas或numpy的问题。在我看来
numpy。其中
仅按条件设置值,因此第二和第三个数组对所有数据进行计数-过滤和非过滤
如果需要,仅对过滤后的值应用某些函数:
mask = df.A.str.contains('_')
df.loc[mask, "B"] = df.loc[mask, "A"].str.split('_').str[1]
在您的解决方案中是错误,但问题与np.where
无关。按\uuu
拆分后,如果不存在值,则获取一个元素列表,因此按[1]
选择列表的第二个值将引发错误:
print (df.A.apply(lambda x: x.split('_')))
0 [a]
1 [a, 1]
2 [b, ]
3 [b, 2, 3]
Name: A, dtype: object
print (df.A.apply(lambda x: x.split('_')[1]))
IndexError: list index out of range
因此,如果性能不重要,因为字符串函数的速度很慢,可以使用以下解决方案:
df["B"] = np.where(df.A.str.contains('_'),
df.A.str.split('_').str[1],
df.A.str[0])
在我看来,
numpy。其中,
只按条件设置值,所以第二个和第三个数组对所有经过过滤和未过滤的数据进行计数
如果需要,仅对过滤后的值应用某些函数:
mask = df.A.str.contains('_')
df.loc[mask, "B"] = df.loc[mask, "A"].str.split('_').str[1]
在您的解决方案中是错误,但问题与np.where
无关。按\uuu
拆分后,如果不存在值,则获取一个元素列表,因此按[1]
选择列表的第二个值将引发错误:
print (df.A.apply(lambda x: x.split('_')))
0 [a]
1 [a, 1]
2 [b, ]
3 [b, 2, 3]
Name: A, dtype: object
print (df.A.apply(lambda x: x.split('_')[1]))
IndexError: list index out of range
因此,如果性能不重要,因为字符串函数的速度很慢,可以使用以下解决方案:
df["B"] = np.where(df.A.str.contains('_'),
df.A.str.split('_').str[1],
df.A.str[0])
Python不是一个简单的语言,因此代码会立即进行计算。生成器/迭代器确实引入了一些懒散,但这不适用于这里
如果我们拆分您的代码行,我们将得到以下语句:
df.A.str.contains(“"”)
df.A.apply(lambda x:x.split(“”“)[1])
df.A.str[0]
np
要看到所有这些情况的发生,我们可以将上述内容重写为显示一些输出的小函数:
def fn_contains(x):
print('contains', x)
return '_' in x
def fn_split(x):
s = x.split('_')
print('split', x, s)
# check for errors here
if len(s) > 1:
return s[1]
def fn_first(x):
print('first', x)
return x[0]
然后,您可以使用以下工具在数据上运行它们:
s = pd.Series(['a','a_1','b_','b_2_3'])
np.where(
s.apply(fn_contains),
s.apply(fn_split),
s.apply(fn_first)
)
你会看到一切都在有序地执行。这基本上就是在“内部”numpy/pandas中执行东西时发生的情况Python不是一个简单的程序,因此代码会立即被评估。生成器/迭代器确实引入了一些懒散,但这不适用于这里
如果我们拆分您的代码行,我们将得到以下语句:
df.A.str.contains(“"”)
df.A.apply(lambda x:x.split(“”“)[1])
df.A.str[0]
Python必须先对这些语句求值,然后才能将它们作为参数传递给np
要看到所有这些情况的发生,我们可以将上述内容重写为显示一些输出的小函数:
def fn_contains(x):
print('contains', x)
return '_' in x
def fn_split(x):
s = x.split('_')
print('split', x, s)
# check for errors here
if len(s) > 1:
return s[1]
def fn_first(x):
print('first', x)
return x[0]
然后,您可以使用以下工具在数据上运行它们:
s = pd.Series(['a','a_1','b_','b_2_3'])
np.where(
s.apply(fn_contains),
s.apply(fn_split),
s.apply(fn_first)
)
你会看到一切都在有序地执行。这基本上就是numpy/pandas内部执行东西时发生的情况我很惊讶df.A.str.split(“''').str[1]
可以工作,我不会想到在列表中使用.str
-访问器。我确实提出了这个解决方案:df.A.apply(lambda x:x.split(“'u'[1]如果“'u”在x else x[0])
。我很惊讶df.A.str.split(''u'.str[1]
有效,不会想到在列表上使用.str
-accessor。我确实提出了这个解决方案:df.A.apply(lambda x:x.split(“')[1]if“”in x else x[0])
。因此它首先计算所有三个内部语句,然后再进入封闭的np.where
。如果没有np,则不知道如何使用第一条语句作为第二条和第三条语句的过滤器。我理解得对吗?听起来不错,已经用一个演示进行了更新,这样你就有希望看到发生了什么。因此,在进入封闭的np.where
之前,它首先计算所有三个内部语句。如果没有np,则不知道如何使用第一条语句作为第二条和第三条语句的过滤器。我理解的对吗?听起来不错,已经更新了一个演示,希望你能看到发生了什么