#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. Да, я понял. Спасибо за ваш ответ и поддержку, ваше здоровье 🙂