Python导入文本文件,其中每行具有不同的列数
我是python新手,我正试图弄清楚如何加载一个数据文件,该文件包含每个时间步的数据块,例如:Python导入文本文件,其中每行具有不同的列数,python,csv,numpy,import,scipy,Python,Csv,Numpy,Import,Scipy,我是python新手,我正试图弄清楚如何加载一个数据文件,该文件包含每个时间步的数据块,例如: TIME:,0 Q01 : A:,-10.7436,0.000536907,-0.00963283,0.00102934 Q02 : B:,0,0.0168694,-0.000413983,0.00345921 Q03 : C:,0.0566665 Q04 : D:,0.074456 Q05 : E:,0.077456 Q06 : F:,0.0744835 Q07 : G:,0.140448 Q08
TIME:,0
Q01 : A:,-10.7436,0.000536907,-0.00963283,0.00102934
Q02 : B:,0,0.0168694,-0.000413983,0.00345921
Q03 : C:,0.0566665
Q04 : D:,0.074456
Q05 : E:,0.077456
Q06 : F:,0.0744835
Q07 : G:,0.140448
Q08 : H:,-0.123968
Q09 : I:,0
Q10 : J:,0.00204377,0.0109621,-0.0539183,0.000708574
Q11 : K:,-2.86115e-17,0.00947104,0.0145645,1.05458e-16,-1.90972e-17,-0.00947859
Q12 : L:,-0.0036781,0.00161254
Q13 : M:,-0.00941257,0.000249692,-0.0046302,-0.00162387,0.000981709,-0.0135982,-0.0223496,-0.00872062,0.00548815,0.0114075,.........,-0.00196206
Q14 : N:,3797, 66558
Q15 : O:,0.0579981
Q16 : P:,0
Q17 : Q:,625
TIME:,0.1
Q01 : A:,-10.563,0.000636907,-0.00963283,0.00102934
Q02 : B:,0,0.01665694
Q03 : C:,0.786,-0.000666,0.6555
Q04 : D:,0.87,0.96
Q05 : E:,0.077456
Q06 : F:,0.07447835
Q07 : G:,0.140448
Q08 : H:,-0.123968
Q09 : I:,0
Q10 : J:,0.00204377,0.0109621,-0.0539183,0.000708574
Q11 : K:,-2.86115e-17,0.00947104,0.0145645,1.05458e-16,-1.90972e-17,-0.00947859
Q12 : L:,-0.0036781,0.00161254
Q13 : M:,-0.00941257,0.000249692,-0.0046302,-0.00162387,0.000981709,-0.0135982,-0.0223496,-0.00872062,0.00548815,0.0114075,.........,-0.00196206
Q14 : N:,3797, 66558
Q15 : O:,0.0579981
Q16 : P:,0,2,4
Q17 : Q:,786
每个块包含许多变量,这些变量中的数据列数可能非常不同。每个timestep块中每个变量的列数可能会更改,但每个timestep块中每个块的变量数是相同的,并且始终知道导出了多少个变量。数据文件中没有关于数据块数(时间步长)的信息
读取数据后,应以每时间步变量的格式加载数据:
Time: | A: | B:
0 | -10.7436,0.000536907,-0.00963283,0.00102934 | ........
0.1 | -10.563,0.000636907,-0.00963283,0.00102934 | ........
0.2 | ...... | ........
如果每个时间步和每个变量的数据列数相同,那么这将是一个非常简单的问题
我想我需要逐行读取文件,在两个循环中,每个块一个循环,然后在每个块中读取一次,然后将输入存储在一个数组中(append?)。每行不断变化的列数现在让我有点困惑,因为我还不太熟悉python和numpy
如果有人能给我指出正确的方向,比如我应该使用哪些函数来相对有效地完成这项工作,那就太好了。File test.csv:
1,2,3
1,2,3,4
1,2,3,4,5
1,2
1,2,3,4
my_cols = ["A", "B", "C", "D", "E"]
pd.read_csv("test.csv", names=my_cols, engine='python')
A B C D E
0 1 2 3 NaN NaN
1 1 2 3 4 NaN
2 1 2 3 4 5
3 1 2 NaN NaN NaN
4 1 2 3 4 NaN
处理数据:
1,2,3
1,2,3,4
1,2,3,4,5
1,2
1,2,3,4
my_cols = ["A", "B", "C", "D", "E"]
pd.read_csv("test.csv", names=my_cols, engine='python')
A B C D E
0 1 2 3 NaN NaN
1 1 2 3 4 NaN
2 1 2 3 4 5
3 1 2 NaN NaN NaN
4 1 2 3 4 NaN
输出:
1,2,3
1,2,3,4
1,2,3,4,5
1,2
1,2,3,4
my_cols = ["A", "B", "C", "D", "E"]
pd.read_csv("test.csv", names=my_cols, engine='python')
A B C D E
0 1 2 3 NaN NaN
1 1 2 3 4 NaN
2 1 2 3 4 5
3 1 2 NaN NaN NaN
4 1 2 3 4 NaN
或者您可以使用
名称
参数
例如:
1,2,1
2,3,4,2,3
1,2,3,3
1,2,3,4,5,6
如果您阅读它,您将收到以下错误:
>>> pd.read_csv(r'D:/Temp/test.csv')
Traceback (most recent call last):
...
Expected 5 fields in line 4, saw 6
但如果您传递名称
参数,您将得到以下结果:
>>> pd.read_csv(r'D:/Temp/test.csv', names=list('ABCDEF'))
输出:
A B C D E F
0 1 2 1 NaN NaN NaN
1 2 3 4 2 3 NaN
2 1 2 3 3 NaN NaN
3 1 2 3 4 5 6
希望它能有所帮助。一种非常简单的方法是在浏览时读取文本文件并创建一个
dict
结构。以下是一个可能实现您的目标的示例(基于您提供的输入):
这将提供一个输出
对象,它是一个具有以下结构的字典:
output = {
'0': {'A': '-10.7436,0.000536907,-0.00963283,0.00102934',
'B': '0,0.0168694,-0.000413983,0.00345921',
...
'Q': '625'},
'0.1': {'A': '-10.563,0.000636907,-0.00963283,0.00102934',
'B': '0,0.01665694',
...
'Q': '786'}
}
我想这和你要找的很匹配。要访问此词典中的一个值,应使用value=output['0.1']['A']
,这将产生'-10.563,0.000636907,-0.00963283,0.00102934'
作为pd导入熊猫
import pandas as pd
res = {}
TIME = None
# by default lazy line read
for line in open('file.txt'):
parts = line.strip().split(':')
map(str.strip, parts)
if len(parts) and parts[0] == 'TIME':
TIME = parts[1].strip(',')
res[TIME] = {}
print('New time section start {}'.format(TIME))
# here you can stop and work with data from previou period
continue
if len(parts) <= 1:
continue
res[TIME][parts[1].lstrip()] = parts[2].strip(',').split(',')
df = pd.DataFrame.from_dict(res, 'columns')
# for example for TIME 0
dfZero = df['0']
print(dfZero)
df = pd.DataFrame.from_dict(res, 'index')
dfA = df['A']
print(dfA)
res={}
时间=无
#默认情况下,延迟行读取
对于打开的行('file.txt'):
parts=line.strip().split(“:”)
地图(str.strip,零件)
如果len(部分)和部分[0]=“时间”:
时间=零件[1]。带(','))
res[TIME]={}
打印('新时间段开始{}'。格式(时间))
#在这里,您可以停止并使用上一个周期中的数据
持续
如果len(parts)这个读卡器类似于卢卡斯的
——每个块都是保存在按时间键控的元字典中的字典。它本可以是一份清单
blocks = {}
with open('stack37354745.txt') as f:
for line in f:
line = line.strip()
if len(line)==0: continue # blank line
d = line.split(':')
if len(d)==2 and d[0]=='TIME': # new block
time = float(d[1].strip(','))
blocks[time] = data = {}
else:
key = d[1].strip() # e.g. A, B, C
value = d[2].strip(',').split(',')
value = np.array(value, dtype=float) # assume valid numeric list
data[key] = value
可以通过迭代获取、显示和重新组织值,如:
for time in blocks:
b = blocks[time]
print('TIME: %s'%time)
for k in b:
print('%4s: %s'%(k,b[k]))
产生:
TIME: 0.0
C: [ 0.0566665]
G: [ 0.140448]
A: [ -1.07436000e+01 5.36907000e-04 -9.63283000e-03 1.02934000e-03]
...
K: [ -2.86115000e-17 9.47104000e-03 1.45645000e-02 1.05458000e-16
-1.90972000e-17 -9.47859000e-03]
TIME: 0.1
C: [ 7.86000000e-01 -6.66000000e-04 6.55500000e-01]
G: [ 0.140448]
A: [ -1.05630000e+01 6.36907000e-04 -9.63283000e-03 1.02934000e-03]
...
K: [ -2.86115000e-17 9.47104000e-03 1.45645000e-02 1.05458000e-16
-1.90972000e-17 -9.47859000e-03]
(我从一个数据行中删除了…
)
或者以准表格式
fmt = '%10s | %s | %s | %s'
print(fmt%('Time','B','D','E'))
for time in blocks:
b = blocks[time]
# print(list(b.keys()))
print(fmt%(time, b['B'], b['D'],b['E']))
制作:
Time | B | D | E
0.0 | [ 0. 0.0168694 -0.00041398 0.00345921] | [ 0.074456] | [ 0.077456]
0.1 | [ 0. 0.01665694] | [ 0.87 0.96] | [ 0.077456]
因为像B
这样的变量可以有不同的长度,所以很难像某种2d数组那样跨时间收集值
通常,最简单的方法是首先将文件加载到某种Python结构中。这种操作几乎必须用Python编写,逐行迭代(除非你让pandas
为你做)
一旦这样做了,你就可以用多种不同的方式重新安排日期,以满足你的需要。有了这个变量,以正确的方式瞄准矩形
numpy
数组是没有意义的 看看这里:@Dot_Py谢谢,但这个解决方案似乎取决于知道最大列数,我不知道。最后一个答案有一个循环,但似乎不起作用。哦,等等。。。你不知道列数吗?我认为这不是一个好的做法。。。因此,您应该重新考虑/重新设计数据库方案,以便在必要时添加更多行。。。不是列。但是您可以循环遍历行并计算“,”发生次数,以获得整个.txt中的最大列数(num\u max\u cols
),然后您可以使用“range(num\u max\u cols)
”命名列。我不同意@Dot\u Py的说法,不知道输入中将出现的列没有问题。我认为你的问题的答案是填充字典对象。我已经写了一个答案,展示了我将如何再次进行测试,但这对我的数据不太起作用-我永远不知道每个块将存在多少列数据,我所知道的只是每个时间步块中有多少个变量(行)。是的,这大部分是按照我的预期工作的。时间记录中有一个愚蠢的\n标记,但无法解决。我没有考虑过字典,因为我将要做很多数组操作,但我假设如果需要的话,我可以简单地将对字典的调用转换为numpy数组。啊,是的。我对答案进行了编辑,添加了一行内容来解决这个问题。请注意,在我建议的代码的最后一行中,您确切地知道自己的位置(时间、列名和列值)。如果需要,您可以很容易地更改最后一行以将此数据放入任何其他结构中。嗯,我在数据文件上尝试此操作时遇到此错误:回溯(最近一次调用):文件“”,第14行,在res[TIME][parts[1].lstrip()]=parts[2]中。条带(“,”)索引器:列表索引超出范围。我需要一些时间来了解原因,但感谢迄今为止的帮助!谢谢,这似乎工作得很好,没有任何错误。我需要用一些合适的数据文件来测试它,看看它是如何运行的。如果我想访问所有时间步的变量A怎么办?数据帧似乎只允许我访问单个时间步的所有变量?@jpmorr您可以更改df=pd.DataFrame.from_dict(res,'index')或df=pd.DataFrame.from_dict(res,'columns'),请参见示例。