我有一个以下 Pandas 数据框,我想根据“时间”、“样本”和“uid”列更改“fmc”列的值。
概念如下:
对于相同的date
,if df.samples == 'C' & df.uid == 'Plot1'
,则对应的行值fmc * 0.4
同理对于同一个date
,if df.samples == 'C' and df.uid == 'Plot2'
,则对应的行值fmc*0.8
对于相同的date
,if df.samples == 'E' & df.uid == 'Plot1'
,则对应的行值fmc * 0.4
同理对于同一个date
,if df.samples == 'E' and df.uid == 'Plot2'
,则对应的行值fmc*0.15
对于相同的date
,if df.samples == 'ns' & df.uid == 'Plot1'
,则对应的行值fmc * 0.2
同理对于同一个date
,if df.samples == 'ns' and df.uid == 'Plot2'
,则对应的行值fmc*0.05
我是 Python 新手,如果我不能很好地解释,我深表歉意,如果您需要更多说明,请告诉我。
time samples uid fmc
0 2015-10-11 C Plot1 98.226352
1 2015-10-11 C Plot2 132.984817
2 2015-10-11 E Plot1 114.147964
3 2015-10-11 E Plot2 110.083699
4 2015-10-11 ns Plot1 113.258977
5 2015-10-11 ns Plot2 113.768023
6 2015-10-19 C Plot1 118.503214
7 2015-10-19 E Plot1 108.733209
8 2015-10-19 ns Plot1 59.316977
9 2015-10-27 C Plot1 104.977531
10 2015-10-27 C Plot2 121.213887
11 2015-10-27 E Plot1 129.575670
12 2015-10-27 E Plot2 118.639048
13 2015-10-27 ns Plot1 103.581065
14 2015-10-27 ns Plot2 102.278469
15 2015-11-17 C Plot1 103.820689
16 2015-11-17 C Plot2 117.333382
17 2015-11-17 E Plot1 143.418932
18 2015-11-17 E Plot2 160.342155
19 2015-11-17 ns Plot1 89.890484
答案 0 :(得分:1)
此代码:
import pandas as pd
data = [
['2015-10-11', 'C', 'Plot1', 98.226352 ],
['2015-10-11', 'C', 'Plot2', 132.984817 ],
['2015-10-11', 'E', 'Plot1', 114.147964 ],
['2015-10-11', 'E', 'Plot2', 110.083699 ],
['2015-10-11', 'ns', 'Plot1', 113.258977 ],
['2015-10-11', 'ns', 'Plot2', 113.768023 ],
['2015-10-19', 'C', 'Plot1', 118.503214 ],
['2015-10-19', 'E', 'Plot1', 108.733209 ],
['2015-10-19', 'ns', 'Plot1', 59.316977 ],
['2015-10-27', 'C', 'Plot1', 104.977531 ],
['2015-10-27', 'C', 'Plot2', 121.213887 ],
['2015-10-27', 'E', 'Plot1', 129.575670 ],
['2015-10-27', 'E', 'Plot2', 118.639048 ],
['2015-10-27', 'ns', 'Plot1', 103.581065 ],
['2015-10-27', 'ns', 'Plot2', 102.278469 ],
['2015-11-17', 'C', 'Plot1', 103.820689 ],
['2015-11-17', 'C', 'Plot2', 117.333382 ],
['2015-11-17', 'E', 'Plot1', 143.418932 ],
['2015-11-17', 'E', 'Plot2', 160.342155 ],
['2015-11-17', 'ns', 'Plot1', 89.890484]
]
df = pd.DataFrame(columns=['time', 'samples', 'uid', 'fmc'], data=data)
print (df.head(10))
df['result'] = df.apply(
lambda item:
(item.fmc * 0.4) if item.samples == 'C' and item.uid == 'Plot1' else \
(item.fmc * 0.8) if item.samples == 'C' and item.uid == 'Plot2' else \
(item.fmc * 0.4) if item.samples == 'E' and item.uid == 'Plot1' else \
(item.fmc * 0.15)if item.samples == 'E' and item.uid == 'Plot2' else \
(item.fmc * 0.2) if item.samples == 'ns'and item.uid == 'Plot1' else \
(item.fmc * 0.05)if item.samples == 'ns'and item.uid == 'Plot2' else None,
axis=1
)
print(df.head(10))
应该产生这个输出:
time samples uid fmc
0 2015-10-11 C Plot1 98.226352
1 2015-10-11 C Plot2 132.984817
2 2015-10-11 E Plot1 114.147964
3 2015-10-11 E Plot2 110.083699
4 2015-10-11 ns Plot1 113.258977
5 2015-10-11 ns Plot2 113.768023
6 2015-10-19 C Plot1 118.503214
7 2015-10-19 E Plot1 108.733209
8 2015-10-19 ns Plot1 59.316977
9 2015-10-27 C Plot1 104.977531
time samples uid fmc result
0 2015-10-11 C Plot1 98.226352 39.290541
1 2015-10-11 C Plot2 132.984817 106.387854
2 2015-10-11 E Plot1 114.147964 45.659186
3 2015-10-11 E Plot2 110.083699 16.512555
4 2015-10-11 ns Plot1 113.258977 22.651795
5 2015-10-11 ns Plot2 113.768023 5.688401
6 2015-10-19 C Plot1 118.503214 47.401286
7 2015-10-19 E Plot1 108.733209 43.493284
8 2015-10-19 ns Plot1 59.316977 11.863395
9 2015-10-27 C Plot1 104.977531 41.991012
Process finished with exit code 0
受 df.apply
的启发,使用 axis=1
并传递包含完整条件集的 lambda 函数,您将在 result
列中获得预期值。
apply
函数会将数据框的列(因为 axis=1
)作为 item
传递给 lambda 函数,用于值系列中的每条记录。 lambda 函数还为系列中的每个给定记录/项目返回相应的 result
值,因此我们无需担心匹配日期/索引值。
参考 pandas.DataFrame.apply
here。
答案 1 :(得分:0)
创建查询
C1=(df.samples.eq('C')&df.uid.eq('Plot1'))|(df.samples.eq('E')&df.uid.eq('Plot1'))
C2=df.samples.eq('C')&df.uid.eq('Plot2')
C4=df.samples.eq('E')&df.uid.eq('Plot2')
C5=df.samples.eq('ns')&df.uid.eq('Plot1')
C6=C5=df.samples.eq('ns')&df.uid.eq('Plot2')
将查询放入列表
conditions=[C1,C2,C4,C5,C6]
列出与列表中每个查询相对应的结果
MULT=[0.4,0.8,0.15,0.2,0.05]
创建临时列并使用 np.select(condition, result) 填充
df['fmc1']=np.select(conditions, MULT,df.fmc)
将结果与 fmc 相乘并删除临时列
df=df.assign(fmc=df['fmc']*df['fmc1']).drop('fmc1',1)
答案 2 :(得分:0)
制作一个接受特征(列)并根据条件返回结果的函数。
def arrange_stuff(col2, col3, col4):
if col2 == 'C' & col3 == 'Plot1'
return col4*0.4
elif ...
return ...
然后通过应用函数来创建一个新特性,如下所示:
df['fmc_new'] = df(lambda x: arrange_stuff(x['samples'],x['uid'],x['fmc']), axis=1)
如果您不需要原来的 fmc 列,您可以简单地将其删除并重命名 fmc_new,或者首先直接分配给它。
答案 3 :(得分:0)
您应该能够使用 itertuples() 来处理这个问题,它允许您浏览数据框的行。考虑到您的样本和 uid 标准涵盖所有日期,我不确定您所说的“同一日期”是什么意思。
fmc_adjusted = []
for row in df.itertuples():
if df.samples == 'C' and df.uid == 'Plot1':
fmc_adjusted.append(row[4]*0.4)
if df.samples == 'C' and df.uid == 'Plot2':
fmc_adjusted.append(row[4]*0.15)
... 依您的不同标准。
我喜欢保留我的专栏,以防我以后需要参考它们。如果要创建新列:
df['fmc_adjusted'] = fmc_adjusted
如果要替换 fmc 列:
df['fmc'] = fmc_adjusted
可能有更快捷、更简洁的方法,但我不知道。