Python pandas 将列表插入单元格

2025-01-10 08:47:00
admin
原创
95
摘要:问题描述:我有一个列表“abc”和一个数据框“df”:abc = ['foo', 'bar'] df = A B 0 12 NaN 1 23 NaN 我想将列表插入到单元格 1B 中,所以我想要这样的结果: A B 0 12 NaN 1 23 ['foo', 'bar'] 我...

问题描述:

我有一个列表“abc”和一个数据框“df”:

abc = ['foo', 'bar']
df =
    A  B
0  12  NaN
1  23  NaN

我想将列表插入到单元格 1B 中,所以我想要这样的结果:

    A  B
0  12  NaN
1  23  ['foo', 'bar']

我怎麼能做到呢?

1)如果我使用这个:

df.ix[1,'B'] = abc

我收到以下错误消息:

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

因为它尝试将列表(包含两个元素)插入到行/列中,而不是插入到单元格中。

2)如果我使用这个:

df.ix[1,'B'] = [abc]

然后插入一个只有一个元素的列表,即“abc”列表([['foo', 'bar']])。

3)如果我使用这个:

df.ix[1,'B'] = ', '.join(abc)

然后它插入一个字符串:(foo, bar)但不是列表。

4)如果我使用这个:

df.ix[1,'B'] = [', '.join(abc)]

然后它插入一个列表,但它只有一个元素(['foo, bar']),而不是我想要的两个(['foo', 'bar'])。

谢谢帮助!


编辑

我的新数据框和旧列表:

abc = ['foo', 'bar']
df2 =
    A    B         C
0  12  NaN      'bla'
1  23  NaN  'bla bla'

另一个数据框:

df3 =
    A    B         C                    D
0  12  NaN      'bla'  ['item1', 'item2']
1  23  NaN  'bla bla'        [11, 12, 13]

我想将“abc”列表插入到df2.loc[1,'B']and/or中df3.loc[1,'B']

如果数据框的列只有整数值和/或 NaN 值和/或列表值,则将列表插入单元格效果很好。如果数据框的列只有字符串值和/或 NaN 值和/或列表值,则将列表插入单元格效果很好。但是,如果数据框的列有整数和字符串值以及其他列,则如果我使用以下方法,则会出现错误消息:df2.loc[1,'B'] = abcdf3.loc[1,'B'] = abc

另一个数据框:

df4 =
          A     B
0      'bla'  NaN
1  'bla bla'  NaN

这些插入件工作完美:df.loc[1,'B'] = abcdf4.loc[1,'B'] = abc


解决方案 1:

由于自 0.21.0 版以来set_value已弃用,您现在应该使用at。它可以将列表插入单元格而不会ValueErrorloc那样引发。我认为这是因为at 总是引用单个值,而loc可以引用值以及行和列。

df = pd.DataFrame(data={'A': [1, 2, 3], 'B': ['x', 'y', 'z']})

df.at[1, 'B'] = ['m', 'n']

df =
    A   B
0   1   x
1   2   [m, n]
2   3   z

您还需要确保要插入的dtype=object具有。例如

>>> df = pd.DataFrame(data={'A': [1, 2, 3], 'B': [1,2,3]})
>>> df.dtypes
A    int64
B    int64
dtype: object

>>> df.at[1, 'B'] = [1, 2, 3]
ValueError: setting an array element with a sequence

>>> df['B'] = df['B'].astype('object')
>>> df.at[1, 'B'] = [1, 2, 3]
>>> df
   A          B
0  1          1
1  2  [1, 2, 3]
2  3          3

解决方案 2:

熊猫> = 0.21

set_value已弃用。 现在您可以使用DataFrame.at按标签设置,以及DataFrame.iat按整数位置设置。

at使用/设置单元格值iat

# Setup
>>> df = pd.DataFrame({'A': [12, 23], 'B': [['a', 'b'], ['c', 'd']]})
>>> df

    A       B
0  12  [a, b]
1  23  [c, d]

>>> df.dtypes

A     int64
B    object
dtype: object

如果要将“B”列第二行的值设置为某个新列表,请使用DataFrame.at

>>> df.at[1, 'B'] = ['m', 'n']
>>> df

    A       B
0  12  [a, b]
1  23  [m, n]

您还可以使用整数位置来设置DataFrame.iat

>>> df.iat[1, df.columns.get_loc('B')] = ['m', 'n']
>>> df

    A       B
0  12  [a, b]
1  23  [m, n]

如果我得到了怎么办ValueError: setting an array element with a sequence

我将尝试使用以下方法重现此问题:

>>> df
    A   B
0  12 NaN
1  23 NaN

>>> df.dtypes
A      int64
B    float64
dtype: object
>>> df.at[1, 'B'] = ['m', 'n']
# ValueError: setting an array element with a sequence.

这是因为您的对象是float64dtype,而列表是objects,因此存在不匹配。在这种情况下,您需要做的是先将列转换为对象。

>>> df['B'] = df['B'].astype(object)
>>> df.dtypes

A     int64
B    object
dtype: object

然后,它就可以工作了:

>>> df.at[1, 'B'] = ['m', 'n']
>>> df
    
    A       B
0  12     NaN
1  23  [m, n]

可行,但不太好用

更奇怪的是,我发现DataFrame.loc如果你传递嵌套列表,你就可以通过破解来实现类似的目的。

>>> df.loc[1, 'B'] = [['m'], ['n'], ['o'], ['p']]
>>> df

    A             B
0  12        [a, b]
1  23  [m, n, o, p]

您可以在此处阅读有关其工作原理的更多信息。

解决方案 3:

df3.set_value(1, 'B', abc)适用于任何数据框。注意“B”列的数据类型。例如,列表不能插入浮点列,在这种情况下df['B'] = df['B'].astype(object)可以提供帮助。

解决方案 4:

快速解决方法

只需将列表放在新列表中,就像下面数据框中对 col2 所做的那样。它之所以有效,是因为 Python 会获取外部列表(列表的列表)并将其转换为列,就好像它包含普通标量项一样,在我们的例子中是列表,而不是普通标量。

mydict={'col1':[1,2,3],'col2':[[1, 4], [2, 5], [3, 6]]}
data=pd.DataFrame(mydict)
data


   col1     col2
0   1       [1, 4]
1   2       [2, 5]
2   3       [3, 6]

解决方案 5:

也获得

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

对我来说,使用 .at 而不是 .loc 并没有什么区别,但强制执行数据框列的数据类型却起了作用:

df['B'] = df['B'].astype(object)

然后我可以将列表、numpy 数组和各种各样的东西设置为数据框中的单个单元格值。

解决方案 6:

正如这篇文章pandas: 如何将列表存储在数据框中?中提到的;数据框中的数据类型可能会影响结果,以及调用数据框或不分配给数据框。

解决方案 7:

我有一个非常容易实现的解决方案。

创建一个临时类来包装列表对象,然后从该类中调用该值。

以下是一个实际的例子:

  1. 假设您想将列表对象插入数据框。

df = pd.DataFrame([
    {'a': 1},
    {'a': 2},
    {'a': 3},
])

df.loc[:, 'b'] = [
    [1,2,4,2,], 
    [1,2,], 
    [4,5,6]
] # This works. Because the list has the same length as the rows of the dataframe

df.loc[:, 'c'] = [1,2,4,5,3] # This does not work. 

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

## To force pandas to have list as value in each cell, wrap the list with a temporary class.

class Fake(object):
    def __init__(self, li_obj):
        self.obj = li_obj

df.loc[:, 'c'] = Fake([1,2,5,3,5,7,]) # This works. 

df.c = df.c.apply(lambda x: x.obj) # Now extract the value from the class. This works. 

创建一个假类来执行此操作可能看起来很麻烦,但它可以有一些实际应用。例如,apply当返回值为列表时,您可以使用它。

Pandas 通常会拒绝将列表插入单元格,但如果您使用此方法,则可以强制插入。

解决方案 8:

我更喜欢.at和.loc。需要注意的是,目标列需要一个dtype( object),它可以处理列表。

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'A': [0, 1, 2, 3],
    'B': np.array([np.nan]*3 + [[3, 33]], dtype=object),
    })
print('df to start with:', df, '
dtypes:', df.dtypes, sep='
')

df.at[0, 'B'] = [0, 100]  # at assigns single elemnt
df.loc[1, 'B'] = [[ [1, 11] ]]  # loc expects 2d input

print('df modified:', df, '
dtypes:', df.dtypes, sep='
')

输出

df to start with:
   A        B
0  0      NaN
1  1      NaN
2  2      NaN
3  3  [3, 33]

dtypes:
A     int64
B    object
dtype: object
df modified:
   A          B
0  0   [0, 100]
1  1  [[1, 11]]
2  2        NaN
3  3    [3, 33]

dtypes:
A     int64
B    object
dtype: object

解决方案 9:

首先将单元格设置为空白。接下来使用 at 将 abc 列表分配给单元格 1,“B”

abc = ['foo', 'bar']
df =pd.DataFrame({'A':[12,23],'B':[np.nan,np.nan]})
df.loc[1,'B']=''
df.at[1,'B']=abc
print(df)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用