【问题标题】:Converting nested list to pandas dataframe with column names使用列名将嵌套列表转换为熊猫数据框
【发布时间】:2020-05-01 15:41:13
【问题描述】:

Image of Original DataFrame

我有一个看起来像这样的嵌套列表。

features = 
[['0:0.084556', '1:0.138594', '2:0.094304\n'],
 ['0:0.101468', '4:0.138594', '5:0.377215\n'],
 ['0:0.135290', '2:0.277187', '3:0.141456\n']
]

嵌套列表中的每个列表都是以逗号分隔的行。 “:”的左侧是列名,右侧是行值。

我想将其转换为 pandas 数据框,如下所示:

  f_0000  |  f_0001  |  f_0002  |  f_0003  |  f_0004  | f_0005
---------------------------------------------------------------
 0.084556 | 0.138594 | 0.094304 | 0.000000 | 0.000000 | 0.000000
 0.101468 | 0.000000 | 0.000000 | 0.000000 | 0.138594 | 0.377215
 0.135290 | 0.000000 | 0.277187 | 0.141456 | 0.000000 | 0.000000

有人可以帮我解决这个问题吗?

原始 DF(但对我来说,它在 pd.read_clipboard 上的格式不正确..)

    ex_id   labels  features
0   0   446,521,1149,1249,1265,1482 0:0.084556 1:0.138594 2:0.094304 3:0.195764 4:...
1   1   78,80,85,86 0:0.050734 1:0.762265 2:0.754431 3:0.065255 4:...
2   2   457,577,579,640,939,1158    0:0.101468 1:0.138594 2:0.377215 3:0.130509 4:...
3   3   172,654,693,1704    0:0.186024 1:0.346484 2:0.141456 3:0.195764 4:...
4   4   403,508,1017,1052,1731,3183 0:0.135290 1:0.277187 2:0.141456 3:0.065255 4:...

【问题讨论】:

  • 这些字符串在列表中吗?或者这是文本文件中的一些“列表”?
  • 这最初是一个数据框,将列表中的所有项目作为单个列。我做了list(train['features'].str.split(' ')) 将其转换为嵌套列表。
  • 特征 = [[0:0.084556, 1:0.138594, 2:0.094304\n], [0:0.101468, 4:0.138594, 5:0.377215\n], [0:0.135290, 2: 0.277187, 3:0.141456\n] ] 这不是一个合适的列表,您可以发送实际列表。
  • @SachinGupta 对此表示歉意。
  • 您可以添加原始数据框的示例吗?从那里拿走可能会更快。

标签: python pandas data-processing


【解决方案1】:

我认为简单的将保持for 循环。

  1. 首先,从给定的features 中选择所有键。

    1. 对于所有元素,我们使用str.split 并提取第一个元素。
    2. 然后,因为我们只想要唯一的键,所以我们使用set。然后,我们将其转换回list 并使用sorted 对键进行排序(如果需要,here 一些细节)。

第一个总结为:

keys = sorted(list(set([elt.split(':')[0] for l in features for elt in l])))
  1. 从上述键创建一个空的dict,并用一个空列表初始化所有键:
data = {k:[] for k in keys}
  1. 遍历所有特征:

    1. 将访问过的所有关键特征保存在 seen 变量中
    2. 添加所有特色键和值
    3. 用不在当前features中的键完成数据
  2. 最终,使用默认构造函数 [pd.DataFrame()] (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 从 out dict 创建数据帧。

  3. 使用 .columns 和字符串格式 (format) 正确格式化列名称。 Here 是一些很好的解释。


说够了,这里是完整代码+插图

features = [["0:0.084556", "1:0.138594", "2:0.094304"],
    ["0:0.101468", "4:0.138594", "5:0.377215"],
    ["0:0.135290", "2:0.277187", "3:0.141456"]
    ]

# Step 1
keys = sorted(list(set([elt.split(':')[0] for l in features for elt in l])))
print(keys)
# ['0', '1', '2', '3', '4', '5']

# Step 2
data = {k:[] for k in keys}
print(data)
# {'0': [], '1': [], '2': [], '3': [], '4': [], '5': []}

# Step 3
for sub in features:
    # Step 3.1
    seen = []
    # Step 3.2
    for l in sub:
        k2, v = l.split(":")        # Get key and value
        data[k2].append(float(v))   # Append current value to data
        seen.append(k2)             # Set the key as seen

    # Step 3.3
    for k in keys:                  # For all data keys
        if k not in seen:           # If not seen
            data[k].append(0)       # Add 0

print(data)
# {'0': [0.084556, 0.101468, 0.13529], 
#     '1': [0.138594, 0, 0], 
#     '2': [0.094304, 0,0.277187],
#     '3': [0, 0, 0.141456],
#     '4': [0, 0.138594, 0],
#     '5': [0, 0.377215, 0]
# }

# Step 4
df = pd.DataFrame(data)
print(df)
#           0         1         2         3         4         5
# 0  0.084556  0.138594  0.094304  0.000000  0.000000  0.000000
# 1  0.101468  0.000000  0.000000  0.000000  0.138594  0.377215
# 2  0.135290  0.000000  0.277187  0.141456  0.000000  0.000000

# Step 5
df.columns = ["f_{:04d}".format(int(val)) for val in df.columns]
print(df)
#      f_0000    f_0001    f_0002    f_0003    f_0004    f_0005
# 0  0.084556  0.138594  0.094304  0.000000  0.000000  0.000000
# 1  0.101468  0.000000  0.000000  0.000000  0.138594  0.377215
# 2  0.135290  0.000000  0.277187  0.141456  0.000000  0.000000

【讨论】:

  • 干得好,非常干净的方法!我试图做类似的事情,但我的 python 技能又失败了!
  • 这太棒了!如果我为“f_1000”之类的列编号,那么这些列将不再按顺序排列,不是吗?
  • 是什么让你这么想的?列在第 1 步排序
  • 例如,如果我有 5000 个特征。首先是 f_0000 列,然后是 f_0001,然后是 f_0010。应该是列 f_0000,然后是 f_0001,然后是 f_0002。但是,我可能可以弄清楚那部分。谢谢!!
  • 太棒了!另一种方法是转换为数字,排序,然后返回字符串(如果需要..):-)
【解决方案2】:

试试这个:

df = pd.DataFrame(data, columns = ['Column name 1'], ['column name 2'])

【讨论】:

  • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
猜你喜欢
  • 2019-10-12
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
  • 2016-09-25
相关资源
最近更新 更多