Tengo un marco de datos como el siguiente. Lo que estoy tratando de hacer es calcular una columna E1 y F1 con una clasificación y un grupo para luego devolver el marco de datos completo. La columna B1 es incremental, pero no necesariamente en 1, pero la ordenación en B1 será
A1 B1 C1 D1
A 8 0.4 1.3
A 1 0.25 1.25
B 5 0.5 1.02
C 2 0.32 1.85
B 1 0.15 1.22
B 4 0.66 1.97
B 3 0.29 1.87
C 1 0.99 1.22
C 3 0.78 1.39
C 4 0.65 1.99
A 2 0.32 1.02
Si solo tuviera un valor A1 como
A1 B1 C1 D1
A 1 0.25 1.25
A 8 0.4 1.3
A 2 0.32 1.02
Mi flujo de trabajo es
df.sort_values(by=['B1'])
df = df.reset_index(drop=True)
l = df.index.values
for i in range(len(l)):
tempZ = df.loc[l[i], 'B1'] - df.loc[l[i-1], 'B1']
tempJ = (df.loc[l [i], 'C1'] - df.loc[l[i-1], 'C1'])
tempI = (df.loc[l [i], 'D1'] - df.loc[l[i-1], 'D1'])
*** DO a whole series of mathematical calculations ***
X = *** Final mathematical calculations ***
Y = *** Final mathematical calculations ***
df.loc[l[i], 'E1'] = tempE
df.loc[l[i], 'F1'] = tempF
Que luego generaría mi marco de datos como se esperaba
A1 B1 C1 D1 E1 F1
A 1 0.25 1.25 7.33 0.33
A 2 0.32 1.02 7.89 0.12
A 8 0.4 1.3 8.65 0.22
Pero quiero hacerlo para todo el marco de datos.
A1 B1 C1 D1 E1 F1
A 1 0.25 1.25 7.33 0.33
A 2 0.32 1.02 7.89 0.12
A 8 0.4 1.3 8.65 0.22
B 1 0.15 1.22 12.32 0.77
B 3 0.29 1.87 1.11 0.12
B 4 0.66 1.97 7.12 0.99
B 5 0.5 1.02 9.25 0.55
C 1 0.99 1.22 2.35 0.123
C 2 0.32 1.85 6.32 1.03
C 3 0.78 1.39 6.33 1.00
C 4 0.65 1.99 12.02 0.33
Entonces, mi marco de datos debe agruparse por A1 y ordenarse en B1. los cálculos se realizan en las columnas C1 y D1, pero también en las columnas anteriores.
Entonces, supongo que mi pregunta es, ¿cuál sería la forma más eficiente de lograr esto con un marco de datos grande en el que necesitaría hacer algún tipo de grupo y luego generar el marco de datos completo con las nuevas columnas?
Datos
data = [['A',8,0.4,1.3],['A',1,0.25,1.25],['B',5,0.5,1.02],['C',2,0.32,1.85],
['B',1,0.15,1.22],['B',4,0.66,1.97],['B',3,0.29,1.87],['C',1,0.99,1.22],
['C',3,0.78,1.39],['C',4,0.65,1.99],['A',2,0.32,1.02]]
df = pd.DataFrame(data, columns = ['A1', 'B1', 'C1', 'D1'])
2 respuestas
Estoy usando el siguiente CSV ( guardado como test.csv ):
A1,B1,C1,D1
A,8,0.4,1.3
A,1,0.25,1.25
B,5,0.5,1.02
C,2,0.32,1.85
B,1,0.15,1.22
B,4,0.66,1.97
B,3,0.29,1.87
C,1,0.99,1.22
C,3,0.78,1.39
C,4,0.65,1.99
A,2,0.32,1.02
El siguiente código se agrupará en A1
y se ordenará en B1
:
import pandas as pd
df = pd.read_csv('test.csv')
res = pd.DataFrame(columns = df.columns.tolist())
for _, df_chnk in df.groupby('A1', sort=True):
df_chnk = df_chnk.reset_index(drop=True).sort_values(by=['B1'], ascending=True)
res = res.append(df_chnk)
res = res.reset_index(drop=True)
print(res)
El código anterior generará el siguiente marco de datos:
A1 B1 C1 D1
0 A 1 0.25 1.25
1 A 2 0.32 1.02
2 A 8 0.40 1.30
3 B 1 0.15 1.22
4 B 3 0.29 1.87
5 B 4 0.66 1.97
6 B 5 0.50 1.02
7 C 1 0.99 1.22
8 C 2 0.32 1.85
9 C 3 0.78 1.39
10 C 4 0.65 1.99
Para realizar la siguiente operación:
tempZ = df.loc[l[i], 'B1'] - df.loc[l[i-1], 'B1']
tempJ = (df.loc[l [i], 'C1'] - df.loc[l[i-1], 'C1'])
tempI = (df.loc[l [i], 'D1'] - df.loc[l[i-1], 'D1'])
Consulte pandas.DataFrame.diff . ¡Puede usarlo en cada uno de los df_chnk
!
Ordenaría los valores por A y B y luego haría cálculos con groupby y aplicaría, por lo que tiene operaciones vectorizadas, en lugar de bucles, que son muy ineficientes:
data = [['A',8,0.4,1.3],['A',1,0.25,1.25],['B',5,0.5,1.02],['C',2,0.32,1.85],
['B',1,0.15,1.22],['B',4,0.66,1.97],['B',3,0.29,1.87],['C',1,0.99,1.22],
['C',3,0.78,1.39],['C',4,0.65,1.99],['A',2,0.32,1.02]]
df = pd.DataFrame(data, columns = ['A1', 'B1', 'C1', 'D1']).sort_values(['A1', 'B1'])
df['new'] = df.groupby('A1').apply(lambda x: ((x['C1'].diff() * x['D1'].diff()) / x['B1'].mean())).droplevel(0)
df
A1 B1 C1 D1 new
1 A 1 0.25 1.25 NaN
10 A 2 0.32 1.02 -0.004391
0 A 8 0.40 1.30 0.006109
4 B 1 0.15 1.22 NaN
6 B 3 0.29 1.87 0.028000
5 B 4 0.66 1.97 0.011385
2 B 5 0.50 1.02 0.046769
7 C 1 0.99 1.22 NaN
3 C 2 0.32 1.85 -0.168840
8 C 3 0.78 1.39 -0.084640
9 C 4 0.65 1.99 -0.031200
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.