我想将数据从文本文件格式化为特定格式。我的数据文件包含超过 120000 行,但我在这里发布了截断的数据。数据文件具有不同频率的 R、L、G、C 数据(此处为 3 行中的 3 个频率(。该文件只有 2 列,第一列是"Freq",第二列是 RLGC 数据之一。现在我想将数据操作为另一种格式(假设目标.txt(。这是数据的链接。我想像这样将其转换为目标文件。
这是我的代码:
import pandas as pd
#create DataFrame from csv with columns f and v
df = pd.read_csv('data_in.txt', sep="s+", names=['freq','v'])
#df = df.astype(float).convert_objects()
#boolean mask for identify columns of new df
m = df['v'].str.endswith('R', 'L', 'G', 'C')
#new column by replace NaNs by forward filling
df['g'] = df['v'].where(m).ffill()
#get original ordering for new columns
cols = df['g'].unique()
#remove rows with same values in v and g columns
df = df[df['v'] != df['g']]
#reshape by pivoting with change ordering of columns by reindex
df = df.pivot('freq', 'g', 'v').rename_axis(None, axis=1).reindex(columns=cols).reset_index()
df.columns = [x.replace('R','R1:1').replace('L','L1:1').replace('G','G1:1').replace('C','C1:1') for x in df.columns]
df.to_csv('target.txt', index=False, sep='t')
但它给出了以下错误:
TypeError: wrapper3() takes from 2 to 3 positional arguments but 5 were given
谁能帮我将其格式化为目标文件。
现在我需要目标文件以外的另一种格式。我需要格式化为">target_2.txt"。这是另一种不寻常的格式类型,也是需要的。您可以看到,每个 R1:1、L1:1、G1:1 和 C1:1 数据现在看起来都像一个数组块(尽管不是数组(。如果你仔细观察,对于freq
,它应该命名为FORMAT Freq
,然后是tab
,然后是:
,然后是tab
,然后是R1:1
。如果你看到,它会像 -FORMAT Freq+tab+:+tab+R1:1
.然后是new line
,然后是2 tabs
,然后是L1:1
。然后又是new line
,然后是2 tabs
,然后是G1:1
。而且,最后C1:1
也是如此.之后是一行空行,然后跟随第一行数据,第二行数据并继续。数据值将根据标题行。
如何执行第二个目标文件?
我正在使用Spyder 3.2.6,其中嵌入了python 3.6.4 64位。
你不能这样使用str.endswith
。对于您似乎在寻找的东西,我会说str.contains
是您寻找 R 或 L 或......如:
m = df['v'].str.contains('R|L|G|C')
然后你的代码直到pivot
.我在pivot
行收到错误,这是由带有nan
的行引起的,因此您可能需要dropna
,并且可以同时rename
列:
df = (df.dropna().pivot('freq', 'g', 'v').rename_axis(None, axis=1)
.reindex(columns=cols).reset_index()
.rename(columns={col:'{}1:1'.format(col) for col in cols}))
df
看起来像:
freq R1:1 L1:1 G1:1 C1:1
0 0.00E+00 2.66E+00 3.00E-07 2.76E-16 1.58E-10
1 1.00E+06 2.89E+00 3.10E-07 1.72E-05 1.46E-10
2 2.00E+06 2.98E+00 3.13E-07 3.43E-05 1.45E-10
3 3.00E+06 3.07E+00 3.15E-07 5.15E-05 1.44E-10
您可以在一些初始清理后使用pivot
执行此操作。
import pandas as pd
df = pd.read_table('data_in.txt', sep='s+', names=['freq','v'])
# Determine where `'freq'` occurs
mask = df.freq == 'freq'
# Create the column headers you want for each measurement
df.loc[mask, 'col_names'] = df.loc[mask, 'v']
df['col_names'] = df.col_names.ffill() + '1:1'
# Pivot to desired output
df = df.loc[~mask].pivot(index = 'freq',
columns ='col_names',
values = 'v').reset_index()
df.columns.name=None
df = df.astype('float')
输出:
freq C1:1 G1:1 L1:1 R1:1
0 0.0 1.580132e-10 2.763283e-16 2.997629e-07 2.661409
1 1000000.0 1.459912e-10 1.716549e-05 3.096696e-07 2.892461
2 2000000.0 1.447848e-10 3.434434e-05 3.130131e-07 2.981991
3 3000000.0 1.440792e-10 5.152409e-05 3.151563e-07 3.066247
我会用这样的常规字符串操作来做到这一点:
#open file
filename='data_in.txt'
file = open(filename,'r')
fileData=file.read()
file.close()
#remove carriage returns
fileData=fileData.replace("r","")
chunkNumber=0
data=[]
for chunk in fileData.split("nnn"):
chunkNumber+=1
chunkType=chunk.split("n")[0].split("t")[1]
firstData=["freq"]
thisData=["%s:%s"%(chunkType,chunkNumber)]
for line in chunk.split("n")[1:]:
entries=line.split(" ")
thisData.append(entries[1])
firstData.append(entries[0])
data.append(thisData)
data=[firstData]+data
string=""
for j in range(5):
for k in data:
string+=k[j]+"t"
string=string[:-1]+"n"
filename='output.txt'
file = open(filename,'w')
file.writelines(string)
file.close()