【问题标题】:Filling in missing data in Python在 Python 中填充缺失的数据
【发布时间】:2015-10-29 21:57:47
【问题描述】:

我希望你能帮我解决一个小问题。 我正在使用一个小型设备,它打印出我保存到文件中的两个属性。设备在 X 和 Y 方向上栅格以形成网格。我有兴趣将这两个属性的相对强度绘制为 X 和 Y 维度的函数。我将数据记录在以逗号分隔的 4 列中(X、Y、属性 1、属性 2)。 网格是按行检查的,因此对于每个 Y 值,它将从相隔几毫米的 X1 移动到 X2。然后它将移动到下一行并重新开始。

我可以用 pandas/numpy 处理 python 中的数据,但是当有任何缺失的行时它不能很好地工作(不幸的是确实发生了)。 我附上了输出样本(并对问题进行了注释):

44,11,500,1
45,11,120,2
46,11,320,3
47,11,700,4
New            << used as my Y axis separator
44,12,50,5
45,12,100,6
46,12,1500,7
47,12,2500,8

但有时会缺少一行或几行,从而无法处理和绘制。目前我无法自动修复它,必须手动修复。 bad 输出如下所示:

44,11,500,1
45,11,120,2
46,11,320,3
47,11,700,4
New         << used as my Y axis separator
45,12,100,5 << missing 44,12...
46,12,1500,6
47,12,2500,7

我知道我期望的行数,因为我知道我的 X 和 Y 范围。

解决这个问题的最佳方法是什么?目前,我手动输入缺少的 X 和 Y 值,并使用值为 0 的属性 1 和 2 填充。这可能很耗时,我想自动化它。我有两个问题。

问题 1:如何自动用 X 和 Y 的对应值以及两个零填充我的缺失数据?这可以从对应于实验范围的预先生成的 X 和 Y 值数组中获得。

问题 2:有没有更好的方法将文件拆分为单独的数组进行绘图(而不是使用“新”行?)例如,通过一个“if”函数输出 X(start ) 和 X(end) 到一个单独的数组?我试过这样做,但没有成功。

我附上了我当前的(粗略)代码:

 df = pd.read_csv('FileName.csv', delimiter = ',', skiprows=0)
 rows = [-1] + np.where(df['X']=='New')[0].tolist() + [len(df.index)]
 dff = {}
 for i, r in enumerate(rows[:-1]):
     dff[i] = df[r+1: rows[i+1]]
 maxY = len(dff)
 data = []
 data2 = []
 for yaxes in range(0, maxY): 
     data2.append(dff[yaxes].ix[:,2])
 <data2 is then used for plotting using matplotlib>

为了回答我的问题 1,我正在考虑使用 'reindex' 和 'reset_index' 函数,但是没有设法使它们起作用。

如果有任何建议,我将不胜感激。

【问题讨论】:

    标签: python numpy pandas dataframe


    【解决方案1】:

    这符合你想要的吗?

    Q1:使用reindex填写X,其他人使用fillna

    Q2:将分隔的 StringIO 传递给 read_csv 更容易(如果您使用 Python 3,请更改)

    # read file and split the input 
    f = open('temp.csv', 'r')
    chunks = f.read().split('New')
    
    # read csv as separated dataframes, using first column as index
    dfs = [pd.read_csv(StringIO(unicode(chunk)), header=None, index_col=0) for chunk in chunks]
    
    def pad(df):
        # reindex, you should know the range of x
        df = df.reindex(np.arange(44, 48)) 
    
        # pad y from forward / backward, assuming y should have the single value
        df[1] = df[1].fillna(method='bfill')
        df[1] = df[1].fillna(method='ffill')
        # padding others
        df = df.fillna(0)
        # revert index to values
        return df.reset_index(drop=False)
    
    dfs = [pad(df) for df in dfs]
    
    dfs[0]
    #     0   1    2  3
    # 0  44  11  500  1
    # 1  45  11  120  2
    # 2  46  11  320  3
    # 3  47  11  700  4
    
    # dfs[1]
    #     0   1     2  3
    # 0  44  12     0  0
    # 1  45  12   100  5
    # 2  46  12  1500  6
    # 3  47  12  2500  7
    

    【讨论】:

      【解决方案2】:

      第一个问题


      我在函数中包含了打印语句来解释这个函数是如何工作的

      In [89]:     
          def replace_missing(df , Ids ):
              # check what are the mssing values
              missing = np.setdiff1d(Ids , df[0])
      
              if len(missing) > 0 :
                  missing_df = pd.DataFrame(data = np.zeros( (len(missing) , 4 )))
                  #print('---missing df---')
                  #print(missing_df)
                  missing_df[0] = missing
                  #print('---missing df---')
                  #print(missing_df)
                  missing_df[1].replace(0 , df[1].iloc[0] , inplace = True)
                  #print('---missing df---')
                  #print(missing_df)
                  df = pd.concat([df , missing_df])
                  #print('---final df---')
                  #print(df)
              return df
      
          ​
      In [91]:
      Ids = np.arange(44,48)
      final_df = df1.groupby(df1[1] , as_index = False).apply(replace_missing , Ids).reset_index(drop = True)
      final_df
      Out[91]:
      0   1   2      3
      44  11  500    1
      45  11  120    2
      46  11  320    3
      47  11  700    4
      45  12  100    5
      46  12  1500   6
      47  12  2500   7
      44  12  0      0
      

      第二个问题


      In [92]:
      group = final_df.groupby(final_df[1])
      
      In [99]:
      separate = [group.get_group(key) for key in group.groups.keys()]
      
      separate[0]
      Out[104]:
      0   1   2   3
      44  11  500 1
      45  11  120 2
      46  11  320 3
      47  11  700 4
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-03
        • 1970-01-01
        • 2014-03-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多