如何在Python中将复杂列表转换为数据框

时间:2020-11-09 15:47:17

标签: python pandas dataframe

我有这样的清单

[9308, '127.05', [{'id': 8568, 'name': 'some product name', 'product_id': 4204, 'variation_id': 0, 'quantity': 1, 'tax_class': '', 'subtotal': '139.00', 'subtotal_tax': '0.00', 'total': '118.15', 'total_tax': '0.00', 'taxes': [], 'meta_data': [], 'sku': '', 'price': 118.15}], 9306, '98.89', [{'id': 8566, 'name': 'some product name', 'product_id': 4200, 'variation_id': 0, 'quantity': 1, 'tax_class': '', 'subtotal': '89.99', 'subtotal_tax': '0.00', 'total': '89.99', 'total_tax': '0.00', 'taxes': [], 'meta_data': [], 'sku': '', 'price': 89.99}]

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

ID   Total Value     Product IDs
9308   127.05        4204
9306   98.89         4200
etc.

还有一些ID可能没有几个产品ID,因此列表应如下所示:

ID   Total Value     Product IDs
9308   127.05        4204
9308   127.05        4200
9308   127.05        5555

有人可以帮助我吗?我是Python的初学者。

3 个答案:

答案 0 :(得分:1)

IIUC,并且您的输入列表的结构确实很好,那么您可以使用如下这样的硬编码:

df_out = pd.concat([pd.DataFrame(l[::3], columns=['ID']), 
                    pd.DataFrame(l[1::3], columns=['Total Value']), 
                    pd.concat([pd.DataFrame(i) for i in l[2::3]], ignore_index=True)
                      .loc[:, 'product_id']], axis=1)

输出:

     ID Total Value  product_id
0  9308      127.05        4204
1  9306       98.89        4200

答案 1 :(得分:1)

您可以使用grouper中的itertools配方轻松完成此操作。 https://docs.python.org/3/library/itertools.html#itertools-recipes

# Copied from itertools recipes link above
from itertools import zip_longest

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

然后,您可以使用它迭代3个数据块,然后将其合并到defaultdict中,以将数据构建为DataFrame的正确格式

import collections

clean_data = collections.defaultdict(list)

for entry_id, total_value, product_json in grouper(data, 3):
    for record in product_json:
        clean_data["id"].append(entry_id)
        clean_data["total_value"].append(total_value)
        clean_data["product_id"].append(record["product_id"])
    
df = pd.DataFrame(clean_data)
print(df)
     id total_value  product_id
0  9308      127.05        4204
1  9306       98.89        4200

这还将处理以下情况:您的数据第三条中有1条以上的记录(例如,如果列表中有2条字典,而不仅仅是1条)

答案 2 :(得分:1)

假设该数组具有ID,总价值和产品信息的结构,该结构被编码为json。如果我们一次遍历该数组中的三个项目,则以下内容应该可以正常工作:

client.on("voiceStateUpdate", function(oldState, newState) {
    if (newState === undefined) {
        return;
    }

    let room = client.channels.cache.get('586962325240676370');
    let voiceChannelID = newState.channelID;

    if (voiceChannelID === room) {
        let channelgit = client.channels.cache.get('757403475129794600');
        newState.setChannel(channelgit);
    }
});

示例输出:

enter image description here

注意:有关如何iterate multiple items at a time的详细信息。 使用json时,我发现先创建一个数据框,然后添加广播到所有数据框行的其他列会更容易。

假设:缺少输入字符串,请关闭“]”,否则不是数组。上面的代码与此输入配合使用。

def unzip(i,v,d):
    return pd.DataFrame(d).assign(ID=i, TotalValue=v )
df = pd.concat([unzip(i,v,d) for i, v, d in zip(*[iter(js)]*3)])
df[['ID','TotalValue', 'product_id']]
相关问题