我希望你能帮我解决一个小问题。 我正在使用一个小设备打印出我保存到文件的两个属性。设备在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;功能,但无法设法使它们工作。
我将不胜感激任何建议。
答案 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