简体   繁体   English

"Python:使用多个标题行写入 CSV"

[英]Python: Write to CSV with multiple header rows

Context语境<\/h3>

I am looking to export a dictionary which contains a list of dictionaries as the value of each key:value<\/em> pair:我正在寻找一个包含字典列表的字典作为每个键的值:值<\/em>对:

 dict = {'key_1': [{'key_a': foo_1, 'key_b': bar_1}, {'key_a': foo_2, 'key_b': bar_2}], 'key_2': [{'key_c': foo_1, 'key_d': bar_1}], {'key_c': foo_2, 'key_d': bar_2}] ...}<\/code><\/pre>

The desired output will be a .csv file which has the keys of the first dictionary (key_1, key_2, etc.), as the first header row, then the keys of the nested dictionaries (key_a, key_b, etc.), as a second header row which corresponds to its respective key.所需的输出将是一个 .csv 文件,其中包含第一个字典的键(key_1、key_2 等)作为第一个标题行,然后是嵌套字典的键(key_a、key_b 等)作为第二个标题行,对应于其各自的键。

An example of the desired output looks like this, where the list index column refers to data stored within the dictionary at each respective index within the list of dictionaries:所需输出的示例如下所示,其中列表索引列指的是存储在字典中字典列表中每个相应索引处的数据:

 ╔════════════╦═══════════════╤═══════════════╗ ║ ║ key_1 │ key_2 ║ ║ List Index ╠═══════╤═══════╪═══════╤═══════╣ ║ ║ key_a │ key_b │ key_c │ key_d ║ ╠════════════╬═══════╪═══════╪═══════╪═══════╣ ║ 0 ║ foo_1 │ bar_1 │ foo_1 │ bar_1 ║ ╟────────────╫───────┼───────┼───────┼───────╢ ║ 1 ║ foo_2 │ bar_2 │ foo_2 │ bar_2 ║ ╟────────────╫───────┼───────┼───────┼───────╢ ║ 2 ║ foo_3 │ bar_3 │ foo_3 │ bar_3 ║ ╚════════════╩═══════╧═══════╧═══════╧═══════╝<\/code><\/pre>  
       

Platform:<\/em><\/strong> Raspberry Pi 3b+, Python 3.6平台:<\/em><\/strong>树莓派 3b+、Python 3.6

<\/blockquote>


Code代码<\/h3>

Currently, I am looking into different options for doing this, so do not have any coherent code which comes near working.目前,我正在研究执行此操作的不同选项,因此没有任何接近工作的连贯代码。 However, in order of preference, here are a few options which I am considering:但是,按照优先顺序,我正在考虑以下几个选项:

  • Use pandas to form an array which mirrors the nature of the desired table.使用 pandas 形成一个反映所需表性质的数组。 Then write this to CSV directly.然后直接将其写入CSV。

    <\/li>

  • Write to CSV from the dictionary data-structure described above.从上述字典数据结构写入 CSV。

     import csv field_names = dict.keys() header2 = {'%s' %dict.keys() : dict[key_1][0].keys()} with open('project_data.csv', 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=field_names) writer.writeheader() # Write header row containing the top field names writer.writerow(header2) #Write row containing the second field names<\/code><\/pre>

    As is evident, this code needs further development to make it work as desired.很明显,此代码需要进一步开发以使其按预期工作。

    <\/li>

  • Another method I have not considered?另一种我没有考虑过的方法?


    <\/li><\/ul>

    The Question问题<\/h3>

    What would be the best approach to write to a CSV in this format?以这种格式写入 CSV 的最佳方法是什么?

    "

so far I have reached here: 到目前为止,我已经到达这里:

d = {'key_1':
    [{'key_a': 'foo_1', 'key_b': 'bar_1'}, 
     {'key_a': 'foo_2', 'key_b': 'bar_2'}], 
    'key_2':
    [{'key_c': 'foo_1', 'key_d': 'bar_1'}, 
     {'key_c': 'foo_2', 'key_d': 'bar_2'}]}
df = pd.DataFrame(d)
df1 = []
for col in df.columns:
    data = df[col].apply(pd.Series)
    data = df1.append(data)
df1 = pd.concat(df1,axis=1)
print(df1)

which gives you: 这给你:

  key_a   key_b    key_c     key_d
0 foo_1   bar_1    foo_1     bar_1 
1 foo_2   bar_2    foo_2     bar_2 

Rest you have to map the respective keys in regards to your original column names and tat can be placed in df1.loc[-1] as an identifier. 剩下的就是您必须映射与原始列名有关的各个键,并且tat可以作为标识符放置在df1.loc[-1]中。 I will update once I get something. 知道后,我会更新。

Here your "List Index" is a merged cell which you can't achieve in a CSV file because it doesn't contain formatting. 在这里,您的“列表索引”是一个合并的单元格,由于它不包含格式,因此您无法在CSV文件中实现。 You can either: 您可以:

a) Write it to a xlsx file ( XlsxWriter is a great library for this) a)将其写入xlsx文件( XlsxWriter是一个很棒的库)

b) Keep it was a CSV but with an unmerged cell as anky_91 suggests b)保持为CSV,但如anky_91所示,具有未合并的单元格

here's a solution for creating fieldnames<\/code> for DictWriter()<\/code> for a dictionary that contains dictionaries and also lists of dictionaries.这是为包含字典和字典列表的字典创建DictWriter()<\/code> fieldnames<\/code>名的解决方案。

You need to walk the structure and generate the fieldnames<\/code> along with a new dict<\/code> that has those new names:您需要遍历结构并生成fieldnames<\/code>名称以及具有这些新名称的新dict<\/code> :

#!/usr/bin/env python3
import csv
import pprint as pp

myDict = {'key_1':
        [{'key_a': 'foo_1', 'key_b': 'bar_1'}, 
         {'key_a': 'foo_2', 'key_b': 'bar_2'}], 
        'key_2':
        [{'key_c': 'foo_1', 'key_d': 'bar_1'}, 
         {'key_c': 'foo_2', 'key_d': 'bar_2'}] }

def generateFieldnames(myDict):
    # create unique fieldnames from a dictionary containing dictionaries
    newDict={}
    fieldnames=[] # DictWriter will create a .csv with these header names
    
    for k,v in myDict.items():
        
        # is a dictionary?
        if (type(v) is dict):
            for kk,vv in v.items():
                print('k={0}, kk={1}, vv={2}'.format(k,kk,vv))
                name='{0}_{1}'.format(k,kk)
                fieldnames.append(name)
                newDict[name]=vv
                
        elif (type(v) is list):
            for item in range(len(v)):
                listItem=v.pop()
                if (type(listItem) is dict):
                    for kk,vv in listItem.items():
                        name='{0}_{1}'.format(k,kk)
                        fieldnames.append(name)
                        newDict[name]=vv
        
        else:
            print('k=[{0}] , v=[{1}]'.format(k,v))
            fieldnames.append(k)
            newDict[k]=v
    
    return fieldnames, newDict


# create fieldnames from the dictionary with lists and dictionaries
fieldnames, newDict=generateFieldnames(myDict)
pp.pprint(fieldnames)
print('\n')
pp.pprint(fieldnames)
print('\n\n')

# write a sample .csv with fieldnames as headers
fd = open('mytest.csv','a')
dw = csv.DictWriter( fd, fieldnames=fieldnames)

dw.writeheader() # write the header row

dw.writerow( newDict )
dw.writerow( newDict )
dw.writerow( newDict )

fd.close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM