【问题标题】:Dataframe operations with nan: dtype not working, vectorize problems使用 nan 的数据框操作:dtype 不起作用,矢量化问题
【发布时间】: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

我一般

  1. 尝试将数据框作为字符串*

  2. 使用 numpy vectorize 应用函数

但是,我遇到了意外行为。

  1. 我在接收数据时指定dtype=str。 应该够了

  2. 我仍然会收到一个 ValueError 指示输入被读取为带有 vectorize 的浮点数。

  3. 我必须使用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 docnp.vectorize只是一个for循环。
  • pandas 对包含字符串的列使用对象 dtype。它不使用numpy 字符串数据类型。对象列还可以包含数字、nan(浮点数)等。

标签: python pandas numpy


【解决方案1】:

np.nan 类型为浮点数,因此“ID”列包含浮点数和字符串。正如第一条评论中提到的,你应该尽量避免使用矢量化,你可以简单地做

df_with_nan['Special ID?'] = pd.isnull(df_with_nan['ID'])

无需转换。

作为旁注,您可以通过运行 type(df_with_nan['ID'][row_idx]) 来检查值的实际类型,其中 row_idx 是整数行索引,对于您所谓的非特殊 ID,它将是 str,对于特殊 ID,它将是 float身份证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    相关资源
    最近更新 更多