У меня есть следующий фрейм данных Pandas, где я хочу изменить значение столбца «fmc» на основе столбцов «время», «образцы» и «uid».

Концепция следующая:

Для того же 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
2
Sher 25 Фев 2021 в 03:08

4 ответа

Лучший ответ

Этот код:

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 и передав лямбда-функцию, содержащую полный набор условий, вы получите ожидаемые значения в столбце result.

Функция apply передаст столбцы фрейма данных (потому что axis=1) лямбда-функции как item для каждой записи в серии значений. Лямбда-функция также возвращает соответствующее значение result для каждой данной записи / элемента в серии, поэтому нам не нужно беспокоиться о сопоставлении значений даты / индекса.

Ссылка для pandas.DataFrame.apply здесь .

1
Rikki 25 Фев 2021 в 01:17

Вы должны иметь возможность использовать 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

Возможно, есть более быстрые и изящные способы сделать это, но я не знаю.

0
BigHeadEd 25 Фев 2021 в 00:36

Сделайте функцию, которая принимает функции (столбцы) и возвращает результат в зависимости от условий.

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 или, возможно, назначить его напрямую.

0
delimiter 25 Фев 2021 в 00:29

Создавать запросы

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 (условие, результат)

df['fmc1']=np.select(conditions, MULT,df.fmc)

Умножьте результат на fmc и удалите временный столбец

df=df.assign(fmc=df['fmc']*df['fmc1']).drop('fmc1',1)
0
wwnde 25 Фев 2021 в 00:22