Как выполнять математические операции{например. diff()} в нескольких столбцах фрейма данных и сохраните результат в том же фрейме данных, что и в новом столбце

#python #pandas #dataframe

Вопрос:

Предположим, у меня есть фрейм данных, подобный этому:

 df=
    p1  v1  p2  v2  p3  v3  p4  v4  p5  v5  p6  v6
0   3   6   5   8   4   4   8   4   9   6   0   0
1   5   0   5   9   0   8   8   5   5   2   2   9
2   6   9   8   6   9   9   9   2   8   4   2   6
3   4   1   8   0   5   9   0   2   1   2   4   8
4   1   4   8   1   3   1   4   9   6   2   6   7
5   5   4   6   5   5   2   3   0   5   5   6   4
6   4   4   9   0   2   1   7   0   1   0   8   8
7   9   1   7   3   5   4   4   4   8   9   3   8
8   1   5   0   5   4   3   6   5   2   3   1   4
9   9   1   7   6   5   3   6   8   8   4   7   5
10  1   6   5   8   2   5   1   5   3   4   5   8
11  8   7   6   6   9   3   5   5   9   7   6   7
 

p и v-это определенные параметры, измеренные для разных выборок (например, 1, 2, 3..и т. Д.). Теперь я хочу умножить все столбцы «p_» на число и использовать diff() все столбцы «v_» для вычитания последующих строк этого столбца.

Я хочу сохранить результаты в одном и том же кадре данных, используя соответствующее имя выборки и первую букву математической операции, например Dv1, Dv2 для вывода df. diff('v1'), df.diff('v2') и т. Д. Аналогично, для столбцов p это будет похоже на Mp1.

Вручную для каждого столбца я могу выполнить операцию и сохранить результаты, но это утомительно(так как количество выборок очень велико), поэтому я хочу автоматизировать ее, используя такие условия, как цикл for.

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

Новый кадр данных должен выглядеть так p1 Mp1 v1 DV1 p2 Mp2 v2 Dv2 p3 Mp3 v3 Dv3....... и т.д.

Ответ №1:

Попробуйте это:

 # Find all columns that starts with p and followed by a number
p = df.columns[df.columns.str.match('pd')]

# Find all columns that starts with v and followed by a number
v = df.columns[df.columns.str.match('vd')]

# Multiply the p columns by 2
mp = df[p].mul(2).add_prefix('M')

# Take a diff of the v columns
dv = df[v].diff().add_prefix('D')

# The display order of the columns
cols = [f'{j}{i}' for i in range(1,7) for j in ['p', 'Mp', 'v', 'Dv']]

# The final result
final = pd.concat([df, mp, dv], axis=1)[cols]
 

Комментарии:

1. Большое Вам спасибо за ваш ценный вклад и поддержку. Поскольку в моем фрейме данных так много столбцов, поэтому для выбора диапазона, который я использовал range(1,len(p) 1) , есть ли лучший способ сделать это?

Ответ №2:

Что-то вроде:

 import pandas as pd
import io

str_data = """
p1,v1,p2,v2,p3,v3,p4,v4,p5,v5,p6,v6
3,6,5,8,4,4,8,4,9,6,0,0
5,0,5,9,0,8,8,5,5,2,2,9
6,9,8,6,9,9,9,2,8,4,2,6
4,1,8,0,5,9,0,2,1,2,4,8
1,4,8,1,3,1,4,9,6,2,6,7
5,4,6,5,5,2,3,0,5,5,6,4
4,4,9,0,2,1,7,0,1,0,8,8
9,1,7,3,5,4,4,4,8,9,3,8
1,5,0,5,4,3,6,5,2,3,1,4
9,1,7,6,5,3,6,8,8,4,7,5
1,6,5,8,2,5,1,5,3,4,5,8
8,7,6,6,9,3,5,5,9,7,6,7
"""

df = pd.read_csv(io.StringIO(str_data))


#Doing this in case you have a pN, but not a vN, or vice versa to avoid errors
p_samples = [int(c[1:]) for c in df.columns if c.startswith('p')]
v_samples = [int(c[1:]) for c in df.columns if c.startswith('v')]
samples = set(p_samples).intersection(v_samples)
samples = sorted(list(samples))

data = {}
mult_num = 7 #not sure what you want to multiply by

for sample in samples:
    p_col = 'p{}'.format(sample)
    v_col = 'v{}'.format(sample)
    
    Mp_col = 'Mp{}'.format(sample)
    Dv_col = 'Dv{}'.format(sample)
    
    data[p_col] = df[p_col]
    data[Mp_col] = mult_num*df[p_col]
    data[v_col] = df[v_col]
    data[Dv_col] = df[v_col].diff()
    
    
new_df = pd.DataFrame(data)
print(new_df)
 

Комментарии:

1.спасибо вам за вашу помощь и вклад. Ваш код идеально подходит для примеров данных, но поскольку вы сначала изменили данные в данные str с помощью a multiline string quote """ """ , мне трудно преобразовать большие данные со многими строками и столбцами в данные str. Я хочу знать, как преобразовать большой кадр данных в данные str.

2. извините, что я должен был объяснить в коде, но я просто использую str_data для создания фрейма данных из вашей таблицы для этого примера. У вас уже есть фрейм данных в памяти каким-то другим способом, что-то вроде pd.read_csv? Вам не нужно возиться со str_data, это просто для того, чтобы я мог получить df, так как у меня нет таких же файлов, как у вас

3. Да, я понял. Спасибо за ваш ответ и поддержку, ваше здоровье 🙂