我想读取一个csv文件,然后将数据作为特定变量存储在标题下。
我的csv文件:
multiplicity
4.123
lattice parameters
1,0,0
0,1,0
0,0,1
atom sites
0,0,0
0.5,0.5,0.5
occupancy
1,0
0,1
我想创建一个代码,该代码可以自动将多重性下的行存储为变量的数据,以此类推。我不能在csv中将诸如multiplicity之类的值硬编码为line [2],因为每行的行数都会改变。我想创建一个循环,该循环将标头之间的数据存储为变量,但是我不确定该怎么做。
理想情况下,我希望代码搜索第一个标头和第二个标头,然后将两者之间的值另存为多重性变量。然后,我希望它找到第二个标头和第三个标头,并将这些值另存为晶格参数。找到第三个标头和第四个标头及其之间的值作为原子位点。最后找到第四个标头和csv的末尾,并将中间的值保存为占用率。
答案 0 :(得分:2)
您可以尝试将行收集到collections.defaultdict()
中。
关于将行分组到其各自的标题,似乎您可以仅检查行是否包含所有字母和空格,并且是csv.reader()
读取的一项。很难说,因为您只显示了数据快照。我在下面的示例中做了这些假设。在确定了查找标题的方式之后,您可以简单地添加所有行,直到找到另一个标题。
我还假设您的普通行包含整数和浮点数。您可以使用ast.literal_eval()
将它们直接转换为适当的类型。
演示:
from csv import reader
from collections import defaultdict
from ast import literal_eval
from pprint import pprint
# Create a dictionary of lists
data = defaultdict(list)
# Open your file
with open('data.csv') as f:
# Get the csv reader
csv_reader = reader(f)
# Initialise current header
# If rows fall under this header, they don't have a header
current_header = None
# Go over each line in the csv file
for line in csv_reader:
# Found header
if len(line) == 1 and all(item.isalpha() or item.isspace() for item in line[0]):
current_header = line[0]
continue
# If we get here, normal line with ints and floats
data[current_header].append(list(map(literal_eval, line)))
pprint(data)
输出:
defaultdict(<class 'list'>,
{'atom sites': [[0, 0, 0], [0.5, 0.5, 0.5]],
'lattice parameters': [[1, 0, 0], [0, 1, 0], [0, 0, 1]],
'multiplicity': [[4.123]],
'occupancy': [[1, 0], [0, 1]]})
现在您有了一个字典,用于存储每个标题及其各自的行。稍后可以对其进行操作,并在需要时将其添加。
以下是打印每个标题及其各自行(嵌套列表)的示例:
for header, rows in data.items():
print("Header: %s, Rows: [%s]" % (header, ",".join(map(str, rows))))
# Header: multiplicity, Rows: [[4.123]]
# Header: lattice parameters, Rows: [[1, 0, 0],[0, 1, 0],[0, 0, 1]]
# Header: atom sites, Rows: [[0, 0, 0],[0.5, 0.5, 0.5]]
# Header: occupancy, Rows: [[1, 0],[0, 1]]
您也可以查看How to use dictionaries in Python,以了解有关字典以及如何操作它们的更多信息。
答案 1 :(得分:2)
我的$ 0.02:
这不是有效的代码,但您可能需要python csv module中的某些内容,可能看起来像这样(RoadRunner的代码更完整,但我认为我们俩沿着相同的路线,最终将获得几乎相同的输出)。
data_dict = {}
import csv
with open('file_name.csv', newline='') as csvfile:
csvreader = csv.reader(csvfile, delimiter=',')
curr_header = "IF THIS IN DICT, SOMETHING IS WRONG"
for row in csvreader:
try: # look for header, if not header, append data
float(row[0])
data_dict[curr_header].append([float(x) for x in row])
except ValueError: # found a header
curr_header = row[0]
data_dict[curr_header] = []
print(data_dict)
答案 2 :(得分:1)
import re
data = {}
lines = list(open("data.csv", 'r'))
for line in lines:
check = line.split(",")[0].strip()
if not re.match("^-?\d+\.?\d*$", check):
key = check
else:
data[key] = data.get(key, []) + [[float(x) for x in line.split(",")]]
和数据字典看起来像:
{'atom sites': [[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
'lattice parameters': [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
'multiplicity': [[4.123]],
'occupancy': [[1.0, 0.0], [0.0, 1.0]]}