Tengo un marco de datos que quiero separar en contenedores y asignar a cada bin el valor medio de los valores en ese bin.

   POA   Egrid           
   200   1.17
   205   0.63
   275   1.08
   325   1.22
   350   0.57

El resultado debería verse como

   POA       Egrid           
 (200,300)   Median of (1.17,0.63,1.08)
 (300,400)   Median of (1.22,0.57)

Traté de escribir dos bucles, pero no pude entender la parte mediana. Cualquier ayuda sería buena.

1
Chinmay 24 jun. 2020 a las 01:54

4 respuestas

La mejor respuesta

Hazlo

s=df.groupby(pd.cut(df.POA,[100,200,300])).Egrid.median().reset_index()
          POA  Egrid
0  (100, 200]  1.170
1  (200, 300]  0.855
1
BEN_YO 23 jun. 2020 a las 23:19

Uso: pd.cut y .groupby y .transform

import pandas as pd
df['POA'] = df['POA'].astype(int)
df['POA'] = pd.cut(df['POA'], [0,99,199, 299, 399], include_lowest=True)
df['Egrid'] = df.groupby('POA')['Egrid'].transform('median')
df = df.drop_duplicates()
df

Editar:

Hay una bandera con pd.cut que es right=False. Si agregamos esto, las categorías son mucho más limpias y en lugar de ir a 99, puede ir a 100.

import pandas as pd
df['POA'] = df['POA'].astype(int)
df['POA'] = pd.cut(df['POA'], [0,100,200, 300,400], include_lowest=True, right=False)
df['Egrid'] = df.groupby('POA')['Egrid'].transform('median')
df = df.drop_duplicates()
df

Salida:

    POA         Egrid
0   [200, 300)  1.080
1   [200, 300)  1.080
2   [200, 300)  1.080
3   [300, 400)  0.895
4   [300, 400)  0.895
1
David Erickson 23 jun. 2020 a las 23:17

Ciertamente no es la forma más eficiente de hacerlo, ¡pero esto funcionaría!

Primero, recreemos una configuración similar:

import numpy as np
import pandas as pd

# make a DataFrame like yours
df = pd.DataFrame([[200, 1.17], [205, 0.63], [275, 1.08], [325, 1.22], [350, 0.57]], columns=["POA", "Egrid"])

Luego, agreguemos las medianas:

# first, define a list of possible ranges from which you want the medians
list_of_ranges = [(200, 300), (300, 400)]

# initialize a column named "Median"
df["Median"] = [0]*df.shape[0]

# apply median to the desired ranges
for a, b in list_of_ranges:
    
    # calculate the median from the desired subset of the dataframe
    median = df[(df['POA'] >= a) & (df['POA'] < b)]["Egrid"].median()
    
    # apply the value where the condition is respected
    df.loc[(df['POA'] >= a) & (df['POA'] < b), 'Median'] = median

Indique si esto no está claro.

0
The Half-Blood Prince 23 jun. 2020 a las 23:09
import pandas as pd
import numpy as np

# Create the dataframe
d = {'POA':[200,205,275,325,350], 'Egrid':[1.17,0.63,1.08,1.22,0.57]}
df = pd.DataFrame(data=d)

# Create bins to group by
bins = [100,200,300,400,500,600,700,800,900,1000]

# For loop to assign each POA to a bin
for bin in bins:
    upper_bin = bin + 100
    df.loc[(df['POA'] >= bin) & (df['POA'] < upper_bin), 'Bin'] = f'{bin} to {upper_bin}'

# Create a pandas pivot_table to summarize the results
# Displays each bin and its median value
df2 = pd.pivot_table(df, index=['Bin'], values=['Egrid'], aggfunc=np.median)
print(df2)
0
kfultz07 24 jun. 2020 a las 18:32