填写Python

时间:2015-10-29 21:57:47

标签: python numpy pandas dataframe

我希望你能帮我解决一个小问题。 我正在使用一个小设备打印出我保存到文件的两个属性。设备在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

但是,有时会丢失一行或几行,因此无法处理和绘制。目前我无法自动修复它并且必须手动完成。 错误输出如下所示:

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:有没有更好的方法将文件拆分为单独的数组以进行绘图(而不是使用&#39; New&#39;行?)例如,通过使用&#39; if&#39;将X(开始)和X(结束)之间的每一行输出到一个单独的数组的函数?我试过这样做但没有成功。

我附上了我当前的(原始)代码:

 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,我正在考虑使用&#39; reindex&#39;和&#39; reset_index&#39;功能,但无法设法使它们工作。

我将不胜感激任何建议。

2 个答案:

答案 0 :(得分:0)

这符合你想要的吗?

Q1:使用X填充reindex,使用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

答案 1 :(得分:0)

第一个问题

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

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