根据熊猫数据框中的其他三列更改一列的值

时间:2021-02-25 00:08:24

标签: python pandas

我有一个以下 Pandas 数据框,我想根据“时间”、“样本”和“uid”列更改“fmc”列的值。

概念如下:

对于相同的dateif df.samples == 'C' & df.uid == 'Plot1',则对应的行值fmc * 0.4

同理对于同一个dateif df.samples == 'C' and df.uid == 'Plot2',则对应的行值fmc*0.8

对于相同的dateif df.samples == 'E' & df.uid == 'Plot1',则对应的行值fmc * 0.4

同理对于同一个dateif df.samples == 'E' and df.uid == 'Plot2',则对应的行值fmc*0.15

对于相同的dateif df.samples == 'ns' & df.uid == 'Plot1',则对应的行值fmc * 0.2

同理对于同一个dateif 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

4 个答案:

答案 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

可能有更快捷、更简洁的方法,但我不知道。