numpy 如何在Pandas中设置dtype np.array的列中的多个值?

6tdlim6h  于 2023-08-05  发布在  其他
关注(0)|答案(4)|浏览(101)

我在Pandas中有一列Numpy数组,类似于:

col1 col2    col3
0     1    a    None
1     2    b  [2, 4]
2     3    c    None

字符串
[2, 4]实际上是np.array([2, 4])。现在我需要估算缺失的值,我有一个数组列表。举例来说:

vals_to_impute = [np.array([1, 2]), np.array([1, 4])]


我试过:

mask = col3.isna()
df.loc[mask, "col3"] = vals_to_impute


这将导致错误:

ValueError: Must have equal len keys and value when setting with an ndarray


我试着转换成Numpy数组,提取列等,没有任何效果。实际上是否可以在矢量化操作中设置此值,或者我必须手动执行循环?

kzmpq1sx

kzmpq1sx1#

我设法使用pd.series而不是list来实现它。我还必须输入这个系列的索引,以便插入正确。也许可以做得更容易。

df = pd.DataFrame({
    "col1": [1, 2, 3],
    "col2": ["a", "b", "c"],
    "col3": [None, np.array([2, 4]), None]
})

mask = df["col3"].isna()
vals_to_impute = pd.Series(
    [np.array([1, 2]), np.array([1, 4])],
    index=mask[mask].index
)

df.loc[mask, "col3"] = vals_to_impute

print(df)

字符串
输出量:

col1 col2    col3
0     1    a  [1, 2]
1     2    b  [2, 4]
2     3    c  [1, 4]

wi3ka0sx

wi3ka0sx2#

使用短循环的一个选项:

mask = df['col3'].isna()
vals = iter(vals_to_impute)

for idx in df.index[mask]:
    df.at[idx, 'col3'] = next(vals, None)

字符串
这也可以使用类似于here的方法来解决,在使用底层numpy数组时利用共享内存:

mask = df['col3'].isna()
arr = df['col3'].to_numpy()
arr[np.where(mask)] = vals_to_impute


修改的 Dataframe :

col1 col2    col3
0     1    a  [1, 2]
1     2    b  [2, 4]
2     3    c  [1, 4]


使用的输入:

df = pd.DataFrame({'col1': [1, 2, 3],
                   'col2': ['a', 'b', 'c'],
                   'col3': [None, np.array([2, 4]), None]})

vals_to_impute = [np.array([1, 2]), np.array([1, 4])]

kt06eoxx

kt06eoxx3#

不知道你的问题到底在哪里,因为你只显示了你的代码的一部分。
对我来说,这工作就像预期的那样:

import pandas as pd
import numpy as np

data = [None, None, np.array([2, 2]), None, None]
df = pd.DataFrame(dict(data = data))

mask = df["data"].isna()
maskdata = [np.array([i, i]) for i in mask[mask].index]

df.loc[mask, "data"] = maskdata

# print(df)
# >>>     data
# >>> 0  [0, 0]
# >>> 1  [1, 1]
# >>> 2  [2, 2]
# >>> 2  [3, 3]
# >>> 2  [4, 4]

字符串

hrirmatl

hrirmatl4#

据我所知,这个问题是由loc影响基于索引匹配的值引起的。
以你为例:

df = pd.DataFrame({"col1":[1,2,3], 
                   "col2":["a","b","c"], 
                   "col3":[None, np.array([2,4]), None]})

字符串
如果你看看

mask = df.col3.isna()
mask


你实际上有:

0     True
1    False
2     True
Name: col3, dtype: bool


因此,尽管您只选择了具有“True”的行,但索引的长度仍为3。此外,您的列表vals_to_impute没有索引,因此Pandas不知道如何影响值。
一个快速的解决方案可能是:

mask = df[df.col3.isna()].index
vals_to_impute = pd.Series([np.array([1, 2]), np.array([1, 4])], index=mask)
df.loc[mask,"col3"] = vals_to_impute


注意事项:

  • 也许有一个更合适的Pandas方式来做到这一点。
  • 据我所知,在DataFrame列中使用nd.arrays并不常见,请注意,以后可能会遇到其他问题。

相关问题