【问题标题】:TypeError: can only concatenate list (not "str") to list - pandas dataframeTypeError:只能将列表(不是“str”)连接到列表 - 熊猫数据框
【发布时间】:2020-09-15 19:24:48
【问题描述】:

我知道已经发布了一个类似的问题,我已经用尽了所有这些问题。我有一个包含以下字段的数据框:

import pandas as pd

df = pd.DataFrame([[0, 1021, 0.00, ["C2"]],
    [1, 1023, 0.00, ["C2"]],
    [2, 1024, 2.00, ["C1", "C4"]]],
    columns=["index", "id", "revenue", "campaign"])

print(df)

导致

   index    id  revenue  campaign
0      0  1021      0.0      [C2]
1      1  1023      0.0      [C2]
2      2  1024      2.0  [C1, C4]

我只想创建一个新列“路径”:如果收入为 0,则路径结束为 Null,如果收入>0,则为收入。路径的开始是“开始”

  index  id    revenue campaign       path
   0    1021    0.00    [C2]       ['Start', 'C2', 'Null']
   1    1023    0.00    [C2]       ['Start', 'C2', 'Null']
   2    1024    2.00    [C1, C4]   ['Start', 'C1', 'C4', 'Revenue']

如果我在下面做一些事情,它会起作用..但我有十亿行要处理,所以看起来效率不高。

for i in range(0,len(df)):
    if(df['revenue'][i] == 0):
        df['path'][i] = ['Start'] + df['campaign'][i] + ['Null']
    else:
        df['path'][i] = ['Start'] + df['campaign'][i] + ['revenue']

但是,如果我在这样的列级别工作,它有时会起作用,但有时会因为我只能将列表连接到列表的错误而中断。

df['path'] = np.where(
   df['revenue'] == 0,
    ['Start'] + df['campaign'] + ['Null'],
    ['Start'] + df['campaign'] + ['revenue'])

有人可以帮我解决这个问题吗?我将不胜感激。

【问题讨论】:

  • 使用.str.cat(...)
  • 嗨 idelaney.. 我试图创建一个.. 但是我得到的 dtypes 和我原来 df 的 dtypes 出来不同.. 我不想误导并放弃了..跨度>
  • @thealchemist - 是的,这可能是个问题。我添加了一个我认为是正确的。
  • @tdelaney: 非常感谢你......非常感谢你的支持
  • 由于pandas 省略了字符串元素的引号,因此很难判断列条目是否包含列表或看起来像列表显示(甚至是数组)的字符串。并且列 dtype 将是object。因此,如果有可能混合,您的代码必须考虑到这一点。

标签: python pandas numpy dataframe data-analysis


【解决方案1】:

可以使用python的.extend列表方法和pd.Series.tolist

list1.extend(list2.tolist().extend(list3))

所以:

df['path'] = np.where(
   df['revenue'] == 0,
    ['Start'].extend(df['campaign'].tolist().extend(['Null'])),
    ['Start'].extend(df['campaign'].tolist().extend(['revenue']))
)

【讨论】:

  • 您好供应商.. 我得到一个 'TypeError: 'NoneType' object is not iterable'
  • @thealchemist 您的某一行似乎有不匹配的数据。
  • 我认为这是因为 .extend() 实际上返回 None (它附加到第一个迭代的第二个迭代的元素,但没有返回)。即使你运行a = ['Start'].extend(['banana']),你也会看到a 是None
【解决方案2】:

看起来您的列campaign 是混合类型:在示例中,您显示的值是列表,但从错误看来,您的数据框中的某处可能有一个字符串,可能还有其他类型.这就是“列表添加”不起作用的原因,因为它希望将列表添加为 [list1] + [list2] + [list3],但在某些特定行中,df["campaign"] 实际上计算为字符串。

解决此问题的一种方法是首先尝试确保列 (pd.Series) 是同质类型。我会做以下事情:

def to_list(item):
    """Maps anything that is not a list to a list"""
    return item if isinstance(item, list) else [item]

df["campaign"]= df["campaign"].apply(to_list)

编辑:

我最初建议您应该继续使用np.where(),但我不确定它是否会起作用。在documentation 的示例中,我们只看到现有变量的数值转换。而且当使用虚拟数据进行尝试时,它也不起作用。

如果编写一个简短的函数并将数据帧映射到它,我会改为(在将所有内容转换为列表之后)。

def concat_cols(row):
    if row["revenue"] == 0:
        return ['Start'] + row['campaign'] + ['Null']
    else:
        return ['Start'] + row['campaign'] + ['Revenue']

df.apply(concat_cols, axis=1)

这不一定更快(甚至 different than 循环遍历数据框,因此您可能需要尝试使用较小的样本。

【讨论】:

  • 嗨 Tania.. 非常感谢您的回复.. 现在我收到 TypeError: can only concatenate str (not "list") to str.. 如果我从 ' 中取出 '[]'开始'我在路径列中得到一个巨大的字符串,这又是坏的..
  • to_list 函数实际上将我的列表变成了这样:[[, ', C, 1, 1, ', ]]。
  • 嗨@thealchemist,看看我修改后的答案。我认为np.where 解决方案无论如何都行不通(至少它不适合我)。 to_list 函数应该可以工作...参见示例 df:df = pd.DataFrame(dict(banana=[['a', 'b', 'c'], None, 1, [], 'c', ['d']]))(具有各种数据类型,以防万一您在“活动”列中有这些数据类型),然后是 df.banana.apply(to_list)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-15
  • 1970-01-01
  • 2020-06-10
  • 2020-06-02
  • 2021-02-14
  • 2021-08-25
相关资源
最近更新 更多