我是熊猫的新手,正在研究索引,尤其是MultiIndex。我有一个这样的DataFrame:
df = pd.DataFrame({
'ID':[1,2,1,2],
'Measurement': ['ScanA', 'ScanA', 'ScanB', 'ScanB'],
'Result':[0.1,0.2,0.5,0.7],
'ResultType':['A','B','C','B']})
piv = df.pivot(index = 'ID', columns = 'Measurement', values = ['Result', 'ResultType'])
这将创建两个索引Result
和Type
,但是我想基于Result
的值来修改Type
索引中的值。
例如,如果Type == 'C'
,那么我希望相应的Result
是-1
。
另一个例子是,如果Type in ('A', 'B')
那么我想将Result
设置为0 if < 0.5 else 1
如何以编程方式做到这一点而又无需遍历每一行/每一列?
piv.Result
的输出如下:
Measurement ScanA ScanB
ID
1 0.0 -1
2 0.0 1
答案 0 :(得分:3)
您可以先修改数据框,然后再旋转
df.loc[df['Type'] == 'C', 'Result'] = -1
df.loc[(df['Type'].isin(['A', 'B'])) & (df['Result'] < 0.5), 'Result'] = 0
df.loc[(df['Type'].isin(['A', 'B'])) & (df['Result'] >= 0.5), 'Result'] = 1
df.pivot(index = 'ID', columns = 'Measurement', values = ['Result', 'Type'])
Result Type
Measurement ScanA ScanB ScanA ScanB
ID
1 0 1 A A
2 0 -1 B C
编辑:使用np.select作为@ Wen-Ben建议的替代方法
cond = [df['Type'] == 'C', (df['Type'].isin(['A', 'B'])) & (df['Result'] < 0.5), (df['Type'].isin(['A', 'B'])) & (df['Result'] >= 0.5)]
choice = [-1, 0, 1]
df['Result'] = np.select(cond, choice)
df.pivot(index = 'ID', columns = 'Measurement', values = ['Result', 'Type'])
答案 1 :(得分:3)
作为Vaishali建议的替代方案,您可以在生成numpy.where
后使用piv
对其进行修改。
t = piv['Type']
r = piv['Result'].astype(float)
piv.loc[:, 'Result'] = np.where(
t == 'A', np.where(r < 0.5, 0, 1), np.where(t == 'C', -1, r))
piv
Result Type
Measurement ScanA ScanB ScanA ScanB
ID
1 0.0 1.0 A A
2 0.2 -1.0 B C
答案 2 :(得分:0)
pandas
库中有一个名为loc()
的方法,该方法使用户可以通过调用其标签来查找行的值。此功能以及熊猫提供的条件选择,使用户可以找到满足某些条件的行(类似于SQL中的WHERE
功能),并为该行中的其他列设置值。使用这些方法,我在代码中添加了一部分,以在'Result'
时将-1
列设置为'Type' == 'A'
。您可以应用相同的结构来基于'Result'
的值更改其他'Type'
行。
df = pd.DataFrame({
'ID':[1,2,1,2],
'Measurement': ['ScanA', 'ScanA', 'ScanB', 'ScanB'],
'Result':[0.1,0.2,0.5,0.7],
'Type':['A','B','A','C']})
piv = df.pivot(index = 'ID', columns = 'Measurement', values = ['Result', 'Type'])
df.loc[df['Type'] == 'C', ['Result']] = -1
print(df)