Python将数据读入数组或列表

时间:2014-04-07 18:39:34

标签: python arrays numpy matplotlib

我需要从文本文件中读取数据,对其进行操作,并将其全部存储在数组或列表或其他数据结构中,以便我可以将其制表,并使用matplotlib进行绘制。

我打算有一个输入声明,以存储治疗日期和时间。输入文件中的日期和时间将从此日期时间中减去,以提供自治疗以来的时间(以分钟或小时为单位)。

首先,我正在使用的输入文件采用以下格式:

!05/04/2014
@1332
Contact Angle (deg)     106.87
Contact Angle Left (deg)    106.90
Contact Angle Right (deg)   106.85
Wetting Tension (mN/m)      -21.13
Wetting Tension Left (mN/m) -21.16
Wetting Tension Right (mN/m)    -21.11
Base Tilt Angle (deg)       0.64
Base (mm)           1.7001
Base Area (mm2)         2.2702
Height (mm)         1.1174
Sessile Volume (ul)     2.1499
Sessile Surface Area (mm2)  6.3842
Contrast (cts)          255
Sharpness (cts)         186
Black Peak (cts)        0
White Peak (cts)        255
Edge Threshold (cts)        105
Base Left X (mm)        2.435
Base Right X (mm)       4.135
Base Y (mm)         3.801
RMS Fit Error (mm)      2.201E-3

@1333
Contact Angle (deg)     105.42
Contact Angle Left (deg)    106.04
Contact Angle Right (deg)   104.80
Wetting Tension (mN/m)      -19.36
Wetting Tension Left (mN/m) -20.12
Wetting Tension Right (mN/m)    -18.59
Base Tilt Angle (deg)       0.33
Base (mm)           1.6619
Base Area (mm2)         2.1691
Height (mm)         0.9837
Sessile Volume (ul)     1.6893
Sessile Surface Area (mm2)  5.3962
Contrast (cts)          255
Sharpness (cts)         190
Black Peak (cts)        0
White Peak (cts)        255
Edge Threshold (cts)        105
Base Left X (mm)        2.397
Base Right X (mm)       4.040
Base Y (mm)         3.753
RMS Fit Error (mm)      3.546E-3

在文件中,每个新日期都以'!'开头。并且采用所示格式(dd / mm / yyyy)。

表格应包含输入文件中的日期时间,接触角度以及自治疗以来的最后几分钟。

下面的代码从文本文件中提取所需的相关信息并将其写入另一个文件,但我不知道存储信息的最佳方式是什么。

with open(infile) as f, open(outfile, 'w') as f2:
    for line in f:
        if line.split():
            if line.split()[0][0] == '!':
                for i in range(1,11):
                    current_date += (line.split()[0][i])
                f2.write(current_date[:2] + ' ' + current_date[3:5] + ' ' + current_date[6:] + '\n')
            current_date = ""
            if line.split()[0][0] == '@':
                for i in range(0,5):
                    measure_time += (line.split()[0][i])
                f2.write(measure_time[1:3] + ":" + measure_time[3:] + '\n')
            if line.split()[0] == "Contact" and line.split()[2] == "(deg)":
                contact_angle = line.split()[-1].strip()
                f2.write("Contact Angle (deg): " + contact_angle + '\n\n')
            measure_time = ""
        else:
            continue

我也一直在使用日期时间,并且有一些代码可以从单个输入中计算自治疗以来的时间,但是我需要这个来在输入文件中应用每个日期和时间。

from datetime import datetime
import numpy as np

dt = input("Enter treatment date and time in format: dd mm yyyy hh:mm\n")
#dt = '27 03 2014 12:06'

dob = datetime.strptime(dt,'%d %m %Y %H:%M')



b = datetime(2014,3,27,16,22,0)
c = b-dob
print(c.seconds)
print(c.seconds/60)
print(c.seconds//3600)

最后,我想使用matplotlib绘制自治疗以来的接触角与时间的关系。

如果有人能帮助我,我会非常感激。

2 个答案:

答案 0 :(得分:4)

以下是解析此类文件的方法。全部存储在包含字典的字典中(乌龟一直向下:)。主键是ID(@smth)。

替代方案是按日期存储,每个项目都是按ID列出的字典。但这对collections.defauldict最容易做,这可能会让你感到困惑。因此,下面的解决方案可能不是最好的,但应该更容易理解。

data = {}

date = ID = values = None

for line in datafile:
    if line.lstrip().startswith('!'):
        date = line[1:].strip()
        print date, line
    elif line.lstrip().startswith('@'):
        ID = line[1:].strip()
        data[ID] = {}
        data[ID]['date'] = date
    elif line.strip(): # line not all whitespace
        if not ID: 
            continue # we skip until we get next ID
        try:
            words = line.split()
            value = float(words[-1]) # last word
            unit = words[-2].lstrip('(').rstrip(')')
            item = {'value': value, 'unit': unit}
            key = ' '.join(words[:-2])
            data[ID][key] = item
        except (ValueError) as err:
            print "Could not parse this line:"
            print line
            continue
    else: # if 'empty' line
        ID = None

我建议您逐行分析这一行,在https://docs.python.org/2/中查找方法。如果你真的卡住了,请在评论中提问,有人可以给你一个指向更具体页面的链接。 GL。

答案 1 :(得分:1)

您显然拥有记录,因此您的数据会以最佳状态进行组织。

示例中的每条记录都以@开头(然后我假设的是一个测量索引)。每个记录都有一个额外的字段:顶部列出的日期。

records = []
record = {}
for line in f:
    kv = line.strip().split('\t')
    if kv[0].startswith('@'):
        record['measurement_date'] = msr_date
        records.append(record)  # store the last record
        record = {}  # make a new empty record
        for n in range(21):
            kv = f.next().strip().split('\t')
            quantity = kv[0].split('(')[0].strip()
            value = float(kv[1])
            record[quantity] = value
    elif kv[0].startswith('!'):
        msr_date = datetime.strptime(kv[0][1:], "%d/%m/%Y")   # append it to the record later
    else: 
        pass  # empty line
records.pop()  # The first record is a dummy record
# the last record has nog been appended yet
record['measurement_date'] = msr_date
records.append(record)

最后,您最终会得到一个列表records的词典。 然后,您可以循环使用它们以更有效的形式存储它们,例如使用numpy structured arrays

arr = np.array([ (d['Contact Angle'], d['msr_date'], d['msr_date'] - treatment_date)
    for d in records ], dtype=[
    ('contact_angle', 'f4'),
    ('msr_date', 'datetime64'),
    ('lapse_time', 'timedelta64')])

请注意,如果datetime64是您需要的格式,则必须查找(请查看this SO question

使用最后一个arr,您可以将所有内容整齐地放在"列"中,但您可以按名称访问它们。你可以举例说明

plt.plot(arr['lapse_time'], arr['contact_angle']) 但是你必须告诉matplotlib使用timedelta参数作为其独立变量,shown here for example