2016-03-30 8 views
0

Ich habe einen Datenrahmen:Pandas zweite Maximalwert pro Gruppe in Datenrahmen

bq_selection_id bq_balance bq_market_id bq_back_price 
0   45094462  185.04  155   1.87 
1   45094462  185.04  155   1.97 
2   45094463  185.04  155   3.05 
3   45094463  185.04  156   3.05 
4   45094464  185.04  156   5.80 
5   45094464  185.04  156   5.80 
6   45094466  185.04  157   200.00 
7   45094466  185.04  157   200.00 
8   45094465  185.04  157   NaN 
9   45094465  185.04  157   NaN 

Ich möchte zwei zusätzliche Spalten haben second_lowest, none_values ​​beide je Gruppe, groupby Markt ID. Ein anderes Wort für die Markt-ID 155 second_lowest 1.97 und es gibt keine NaN-Werte, daher ist none_values ​​False. Ich möchte etwas wie bekommen:

bq_selection_id bq_balance bq_market_id bq_back_price second_lowest none_val 
0   45094462  185.04  155   1.87 1.97  False 
1   45094462  185.04  155   1.97 1.97  False 
2   45094463  185.04  155   3.05 1.97  False 
3   45094463  185.04  156   3.05 5.80  False 
4   45094464  185.04  156   5.80 5.80  False 
5   45094464  185.04  156   6.40 5.80  False 
6   45094466  185.04  157   1.00 1.70  True 
7   45094466  185.04  157   1.70 1.70  True 
8   45094465  185.04  157   NaN 1.70  True 
9   45094465  185.04  157   NaN 1.70  True 

Können Sie mir bitte damit helfen?

+0

könnten Sie bitte plädieren Wie soll man '1,70' für' bq_market_id == 157' bekommen? – MaxU

+0

Grundsätzlich gruppierte ich alle Werte möglicherweise mit .groupby ('bq_market_id') und nehme dann den nächsten min/kleinsten Wert in der Gruppe mit der ID 157 (1.00, 1.70, NaN, NaN), so dass der min Wert 1.00 und der zweit kleinste ist 1.70 –

Antwort

0

Wie sei:

gb = df.groupby('bq_market_id') 
df['second_lowest'] = gb.bq_back_price.apply(lambda x: x.sort_values(ascending=False).iloc[1])[df.bq_market_id] 
df['none_val'] = gb.bq_back_price.apply(lambda x: x.isnull().values.any())[df.bq_market_id] 
+0

Damit werden NaN-Werte vor reellen Zahlen angegeben. Dies ergibt den höchsten reellen Wert für den Fall, dass NaNs in einer Gruppe vorhanden sind. – mdurant

3

Kombination Ideen in Ihren bisherigen Fragen verwendet (1, 2), könnten Sie groupby/transform verwenden, um einen neuen Wert für jede Zeile in dem Datenrahmen zuzuordnen:

import numpy as np 
import pandas as pd 
pd.options.display.width = 1000 

df = pd.DataFrame(
    {'bq_back_price': [1.87, 1.97, 3.05, 3.05, 5.8, 5.8, 200.0, 200.0, np.nan, np.nan], 
    'bq_balance': [1850.4, 1850.4, 1850.4, 1850.4, 1850.4, 1850.4, 1850.4, 
        1850.4, 1850.4, 1850.4], 
    'bq_market_id': [155, 155, 155, 156, 156, 156, 157, 157, 157, 157], 
    'bq_selection_id': [45094462, 45094462, 45094463, 45094463, 45094464, 
         45094464, 45094466, 45094466, 45094465, 45094465]}) 

grouped = df.groupby('bq_market_id')['bq_back_price'] 
df['second_lowest'] = grouped.transform(lambda x: x.nsmallest(2).max()) 
df['has_null'] = grouped.transform(lambda x: pd.isnull(x).any()).astype(bool) 
print(df) 

ergibt

bq_back_price bq_balance bq_market_id bq_selection_id second_lowest has_null 
0   1.87  1850.4   155   45094462   1.97 False 
1   1.97  1850.4   155   45094462   1.97 False 
2   3.05  1850.4   155   45094463   1.97 False 
3   3.05  1850.4   156   45094463   5.80 False 
4   5.80  1850.4   156   45094464   5.80 False 
5   5.80  1850.4   156   45094464   5.80 False 
6   200.00  1850.4   157   45094466   200.00  True 
7   200.00  1850.4   157   45094466   200.00  True 
8   NaN  1850.4   157   45094465   200.00  True 
9   NaN  1850.4   157   45094465   200.00  True 
+0

Danke. Genau das habe ich gebraucht. Ich habe versucht, es durch .apply, aber natürlich zu tun ist viel besser –

+0

Ich bekomme "Kann nicht Methode% r mit dtype% s" zu einem bestimmten Zeitpunkt "Kann nicht Methode Nsmallest mit Dtype-Objekt verwenden. Weißt du, warum ich bekommen könnte Dieser Fehler irgendwann? @unutbu –

Verwandte Themen