【发布时间】:2019-12-11 01:46:38
【问题描述】:
我经常有这样的缺少 ID 的数据框:
ID Price
0 1000 900
1 1001 100
2 1002 150
3 NaN 600
我想对 ID 应用某种逻辑来确定记录是否特殊,以获得这种输出:
ID Price Special ID?
0 1000 900 False
1 1001 100 False
2 1002 150 True
3 nan 600 False
我一般
尝试将数据框作为字符串*
使用 numpy
vectorize应用函数
但是,我遇到了意外行为。
我在接收数据时指定
dtype=str。 应该够了我仍然会收到一个 ValueError 指示输入被读取为带有
vectorize的浮点数。我必须使用
astype(str)再次转换该列。 不需要的额外步骤? **
我对正在发生的事情有一个猜测***,但我首先想听听其他人的意见。
您可以在下面运行的代码:
import pandas as pd
import numpy as np
# My data comes in with some empty IDs, but these rows are still usable.
data_with_nan = {'ID':['1000','1001','1002', np.nan],
'Price':['900','100','150', '600']}
# I set dtype to str.
df_with_nan = pd.DataFrame(data_with_nan,dtype=str)
# My console tells me that the ID column is 'object'. I interpret this to mean the
# column only contains objects (which apparently is pandas' shorthand for string).
#Seems to have worked.
df_with_nan.dtypes
def special_id(id):
"""Identify IDs that have 2 in them"""
# I assume that using the dtype of str converts np.nan to 'NaN'.
if '2' in id:
return True
else:
return False
df_with_nan['Special IDs'] = np.vectorize(special_id)(df_with_nan['ID'])
# However, this assumption was incorrect:
# TypeError: argument of type 'float' is not iterable
# Maybe I can use an if condition to check if the argument is none?
def special_id_with_check(id):
"""Identify IDs that have 2 in them"""
if id:
if '2' in id:
return True
df_with_nan['Special ID?'] = np.vectorize(special_id_with_check)(df_with_nan['ID'])
# This continues to return the same error:
# TypeError: argument of type 'float' is not iterable
# Therefore, I must explicitly cast this column as string (even though specifying dtype
# should have done this for me?)
df_with_nan['ID'] = df_with_nan['ID'].astype(str)
df_with_nan
df_with_nan['Special ID?'] = np.vectorize(special_id)(df_with_nan['ID'])
# Now it works.
*我的理解是 nan 作为浮点数出现,因此将数据帧作为浮点数导入将继续使 nans 出现问题。我希望当我将数据框作为字符串接收时,nan 会变成 'NaN'
**你可能会问,“为什么不让你的函数检查输入是否为空?”我有,但不知何故在使用vectorize 时我仍然收到ValueError。
***我的猜测是,正在发生的事情是 dtype 只转换非空值。在这种情况下,我真正应该做的是将 dtype 排除在外,然后在我的函数调用的最后一分钟转换为字符串,就像这样 -
df_with_nan['Special ID?'] = np.vectorize(special_id)(df_with_nan['ID'].astype(str))
这种方法让我觉得很奇怪。我宁愿把所有类型的东西都放在前面。
【问题讨论】:
-
尽管名字很花哨,但根据the doc,
np.vectorize只是一个for循环。 -
pandas对包含字符串的列使用对象 dtype。它不使用numpy字符串数据类型。对象列还可以包含数字、nan(浮点数)等。