为什么 np.where 将我的一些数据转换为 NaN 值?

Why is np.where transforming some of my data into NaN values?

提问人:Jeff Gordon 提问时间:11/2/2023 更新时间:11/3/2023 访问量:85

问:

如果列中存在\n,我想拆分数据值。这是我的原始数据列的片段(请注意,我将此列转换为数据类型):object

0               881567905
1               881046000
2               881046025
3               882935053
4               881006805
5               882130610
6               882036810
7               882428300
8               882428400
9    884343355\n183055900

我拆分了数据,然后在数据具有使用该函数创建的多个列表元素的任何位置返回一个列表。虽然它确实在一定程度上实现了这一点,但它也创造了随机值。'\n'np.where()Nan

0                 881567905
1                 881046000
2                 881046025
3                       NaN
4                       NaN
5                       NaN
6                       NaN
7                 882428300
8                 882428400
9    [884343355, 183055900]

正如你所看到的,在未转换的值和被 NaN 替换的值中,实际上没有任何长度、数据类型或结构差异。我用来拆分和替换的代码是:

file_no = df['file_no'].str.split("\n")
df['file_no'] = np.where(file_no.str.len()==1,file_no.str[0],file_no)

我在结构非常相似的其他列上使用了它,它没有创建这些值。我还重新加载了我的环境,以防我搞砸了较小的步骤,但在此之前唯一的代码是这样的:NaN

df = r'Z:\clients.xlsx'
df = pd.read_excel(path,sheet_name="Master List",header=0,engine="openpyxl")
df = df.rename(columns={'Our File #':'file_no', 'ID #':'ID'})
df = df.astype({'file_no':'object'})
df = df[df.file_no.notnull()]

有没有人知道为什么这些值可能会取代这些熊猫值?NaN

python pandas 数据帧 numpy nan

评论

0赞 Mustafa Aydın 11/2/2023
我怀疑其中一些882935053值被保留为数字,pandas 的 .str.split 会根据这些数字返回 NaN,因为它无法拆分非字符串。所以 np.where 不是我应该受到责备的,我相信,也许尝试而不是反对df = df.astype({"file_no": "str"})
0赞 Jeff Gordon 11/2/2023
它仍然给了我 NaN 值,但我最终找到了解决方案。.创建了所需的输出!df['file_no'] = df['file_no'].apply(lambda x: x.split('\n') if isinstance(x, str) and '\n' in x else x)
0赞 Klops 11/2/2023
它对我有用,当使用正确的字符串输入您的示例时
0赞 hpaulj 11/3/2023
当试图理解他们自己看 3 个论点时。它还有助于在分配回 tio 帧之前查看 wherree 的结果。还要注意 dtype 和 type。Pandas 不会在字符串上显示引号。where

答:

0赞 Jeff Gordon 11/2/2023 #1

我发现使用 .apply 方法效果很好!如果有更好的方法,我愿意学习另一种解决方案,但这效果很好! 输出:df['file_no'] = df['file_no'].apply(lambda x: x.split('\n') if isinstance(x, str) and '\n' in x else x)

0                  881567905
1                  881046000
2                  881046025
3                  882935053
4                  881006805
5                  882130610
6                  882036810
7                  882428300
8                  882428400
9     [884343355, 183055900]
10                 884080135
11                 881076100
12                 885052617
13                 885148004
14                 874545945
1赞 BeRT2me 11/3/2023 #2

我认为您被以下事实所困扰:默认情况下,当拆分器超过一个字符时。regexTruepd.Series.str.split

# Force conversion to strings
df.file_no = df.file_no.astype(str)

# Split on `\\n` with regex=False - you may actually just need `\n`
df.file_no = df.file_no.str.split("\\n", regex=False)

# Your np.where was fine, but can be simplified with `pd.Series.mask`
df.file_no = df.file_no.mask(df.file_no.str.len().eq(1), df.file_no.str[0])

print(df)

输出:

                  file_no
0               881567905
1               881046000
2               881046025
3               882935053
4               881006805
5               882130610
6               882036810
7               882428300
8               882428400
9  [884343355, 183055900]