python - 使用集合创建列会复制集合 n 次
问题描述
我在使用 pandas 时遇到了这种我不太知道如何解释的意外行为,并且在 SO 中没有找到任何相关问题。
从列表字典创建数据框时,正如预期的那样,我们将迭代中的每个元素放入给定的列中的新行中key
:
pd.DataFrame({'a':[1,2,3]})
a
0 1
1 2
2 3
但是,尝试对 a 执行相同操作会set
产生:
pd.DataFrame({'a':{1,2,3}})
a
0 {1, 2, 3}
1 {1, 2, 3}
2 {1, 2, 3}
所以似乎该集合被复制到它实际包含的元素数量,即 3。
我知道为此使用集合并没有什么意义,因为集合根据定义是无序的集合。但是我找不到这种行为背后的任何参考或解释。这是在文档中的某处指定的吗?这背后有什么明显的原因让我想念吗?
pd.__version__
# '1.0.0'
解决方案
问题出在extract_index
,也有点sanitize_array
。给出完整的演练:
import pandas as pd
from pandas.core.internals.construction import init_dict
#pd.DataFrame({'a':{1,2,3}})
data = {'a': {1,2,3}}
index = None
columns = None
dtype = None
从 dict 构造将通过这个块
elif isinstance(data, dict):
mgr = init_dict(data, index, columns, dtype=dtype)
您可以看到索引不正确:
BlockManager
Items: Index(['a'], dtype='object')
Axis 1: RangeIndex(start=0, stop=4, step=1)
ObjectBlock: slice(0, 1, 1), 1 x 4, dtype: object
发生这种情况是因为init_dict
这样做,它传递arrays=[{1, 2, 3}]
给extract_index
并且 pandas 认为一个集合是list_like
。这意味着它将这个集合的长度作为您的索引长度。
from pandas.core.dtypes.common import is_list_like
is_list_like({1,2,3})
#True
另一个问题是由于ndim
存储列表或集合的数组不同,因此底层np.array
的创建方式不同。这被埋在这里
np.array({1,2,3}).ndim
#0
np.array([1,2,3]).ndim
#1
因此,该集合被视为“标量”,它被广播到上面指定的整个 RangeIndex 成为array([{1, 2, 3}, {1, 2, 3}, {1, 2, 3}], dtype=object)
,而列表保持为array([1, 2, 3])
因为它在提取索引时遇到问题,所以简单的解决方法是指定索引,这样它就不会经历任何这些。
pd.DataFrame({'a': {1,2,3}}, index=[0])
# a
#0 {1, 2, 3}
推荐阅读
- azure - 使用 Azure AD 成功进行身份验证后,Azure OAuth 身份验证无法重定向
- javascript - 使用 Quasar Framework 和 i18n 时,字符将无法正确显示
- c++ - 查找给定排序数组中不存在的最小数字 >= x
- google-cloud-platform - gcp:资源类型的事件不一致。存储桶缺少“操作”
- javascript - 使用jQuery的淡出左和淡入右动画
- google-sheets - 谷歌电子表格 ImportXML
- jquery - 如何在 ajax 中为 laravel 的模态窗口使用 Get 和 Post 方法
- python - 使用 Pydantic 创建 CSV 行
- terraform - Terraform 脚本成功创建资源但以错误结束
- kotlin - Kotlin 扩展函数 vs utils/helpers