【问题标题】:Data formatting and manipulation in PythonPython中的数据格式化和操作
【发布时间】:2019-01-21 18:09:51
【问题描述】:

我想将文本文件中的数据格式化为特定格式。我的数据文件包含超过 120000 行,但我在这里发布了截断的数据。数据文件具有不同频率的 R、L、G、C 数据(这里 3 行中的 3 个频率)。该文件只有 2 列,第 1 列是“Freq”,第 2 列是 RLGC 数据之一。现在我想将数据操作为另一种格式(比如说,目标 .txt)。这是数据的link。我想把它转换成this这样的目标文件。

这是我的代码:

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 位。

【问题讨论】:

    标签: python python-3.x pandas dataframe data-manipulation


    【解决方案1】:

    我会用这样的常规字符串操作来做到这一点:

    #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("\n\n\n"):
        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() 
    

    【讨论】:

      【解决方案2】:

      经过一些初步清理后,您可以使用 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
      

      【讨论】:

      • ffill 期间重命名列名是个好主意 :) +1
      • 非常感谢。它也奏效了。我已经更新了另一个最重要的不寻常格式的问题。你能检查一下吗?我也上传了第二个目标文件。
      【解决方案3】:

      您不能以这种方式使用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
      

      【讨论】:

      • 非常感谢。有效。我已经更新了另一个最重要的不寻常格式的问题。你能检查一下吗?我也上传了第二个目标文件。
      • 它起作用了,但是当我的数据足够大并且数据之间的步长在减小时,数据不是单调的,同时保存在新的数据帧中。我创建了另一个问题。你能看看吗?这是link
      猜你喜欢
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多