【问题标题】:how to split one column into many columns and count the frequency如何将一列分成多列并计算频率
【发布时间】:2016-02-09 08:05:09
【问题描述】:

给定一张表格,这是我想到的问题

   Id   type
0   1    [a,b]
1   2     [c]
2   3     [a,d]

我想把它转换成以下形式:

   Id     a  b  c  d
0   1     1  1  0  0
1   2     0  0  1  0
2   3     1  0  0  1

我需要一种非常有效的方法来转换大表。欢迎任何意见。

======================================

我收到了几个很好的答案,非常感谢您的帮助。

现在出现了一个新问题,我的笔记本内存不足以使用pd.dummies生成整个数据帧。

有没有办法逐行生成一个稀疏向量然后堆叠在一起?

【问题讨论】:

  • 你知道type中所有可能出现的值吗?
  • @shanmuga,是的,我可以预先快速计算出所有不同的类型
  • 您的type 列是由字符串还是由字符串列表组成的?
  • @DSM,它是json文件中的列表,当我将它读入数据框时,它变成了字符串,但[符号被保留了。
  • 所以print(type(df["type"].iloc[0]))<class 'str'>

标签: pandas dataframe


【解决方案1】:

试试这个

>>> df
   Id    type
0   1  [a, b]
1   2     [c]
2   3  [a, d]
>>> df2 = pd.DataFrame([x for x in df['type'].apply(
...           lambda item: dict(map(
...                                 lambda x: (x,1), 
...                             item)) 
...           ).values]).fillna(0)
>>> df2.join(df)
   a  b  c  d  Id    type
0  1  1  0  0   1  [a, b]
1  0  0  1  0   2     [c]
2  1  0  0  1   3  [a, d]

它基本上将 list 列表转换为 dict 列表并从中构造一个 DataFrame

[ ['a', 'b'], ['c'], ['a', 'd'] ] # 列表列表
[ {'a':1, 'b':1}, {'c':1}, {'a':1, 'd':1} ] # 字典列表 用这个制作DataFrame

【讨论】:

  • @3c。你的数据有多大?类型有多少行和多少个不同的值?我用 100 万行和 4 个不同的值对其进行了测试。它在 4-6 秒内完成。
  • 40,000 行,大约 7000 列。这个表应该不会很大,但是我的4G内存笔记本在使用pd.get_dummies时会产生内存不足@
  • @3c。 4GB 应该足以处理这个。如果您遇到内存错误,您的代码需要更多优化。
  • 我也试过你的建议使用df.type.apply(lambda x: pd.Series([1]*len(x), index=x)) 。但是,由于类型列表中的某些条目采用'Old El Paso\u2122 mild red enchilada sauce' 的形式。因此我收到了InvalidIndexError: Reindexing only valid with uniquely valued Index objects。似乎\u2122 使重新索引无效。
  • @3c。使用 utf-8 编码读取文件。 fin = open('a.json', encoding='utf-8'); df = pd.read_json(fin);
【解决方案2】:

试试这个:

pd.get_dummies(df.type.apply(lambda x: pd.Series([i for i in x])))

解释一下:

df.type.apply(lambda x: pd.Series([i for i in x]

为您的列表中的索引位置提供一列。然后您可以使用get dummies 来获取每个值的计数

pd.get_dummies(df.type.apply(lambda x: pd.Series([i for i in x])))

输出:

    a   c   b   d
0   1   0   1   0
1   0   1   0   0
2   1   0   0   1

【讨论】:

  • 这真的很简洁很好。非常感谢。唯一的问题是我的电脑内存不足。也许我可以切换到 16GB 内存的桌面,或者我可以将虚拟矩阵存储为稀疏形式?
  • 如果它是一个字符串,而不是一个列表,那么你可以使用字符串方法split()。我已将其添加到答案中(您可能需要先处理方括号
  • @JAB 您可以通过将代码修改为 df.type.apply(lambda x: pd.Series([1]*len(x), index=x)) 来避免制造假人
  • @JAB,我的错,它是列表而不是字符串。
  • 我不确定我是否明白.apply(lambda x: pd.Series([i for i in x])) 的意思。 .apply(pd.Series) 不会产生完全相同的东西吗?
猜你喜欢
  • 2022-01-18
  • 1970-01-01
  • 2018-09-25
  • 2020-03-06
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 2013-12-28
相关资源
最近更新 更多