2015-06-03 8 views
6

मैं डेटा फ्रेम पर एक कॉलम बनाने की कोशिश कर रहा हूं जिसमें कम से कम कॉलम ए (मान कॉलम) है, जिसके लिए कॉलम बी (आईडी कॉलम) का एक विशेष मूल्य है। मेरा कोड वास्तव में धीमा है। मैं ऐसा करने के लिए एक तेज़ तरीका ढूंढ रहा हूं।कॉलम मान (पायथन पांडा) द्वारा डेटाफ्रेम स्लाइस पर गणना फ़ंक्शन खोजने का सबसे तेज़ तरीका

def apply_by_id_value(df, id_col="id_col", val_col="val_col", offset_col="offset", f=min): 
    for rid in set(df[id_col].values): 
     df.loc[df[id_col] == rid, offset_col] = f(df[df[id_col] == rid][val_col]) 
    return df 

और उपयोग का उदाहरण:

import pandas as pd 
import numpy as np 
# create data frame 
df = pd.DataFrame({"id_col":[0, 0, 0, 1, 1, 1, 2, 2, 2], 
        "val_col":[0.1, 0.2, 0.3, 0.6, 0.4, 0.5, 0.2, 0.1, 0.0]}) 

print df.head(10) 
# output 
    id_col val_col 
0  0  0.1 
1  0  0.2 
2  0  0.3 
3  1  0.6 
4  1  0.4 
5  1  0.5 
6  2  0.2 
7  2  0.1 
8  2  0.0 

df = apply_by_id_value(df) 
print df.head(10) 
# output 

    id_col val_col offset 
0  0  0.1  0.1 
1  0  0.2  0.1 
2  0  0.3  0.1 
3  1  0.6  0.4 
4  1  0.4  0.4 
5  1  0.5  0.4 
6  2  0.2  0.0 
7  2  0.1  0.0 
8  2  0.0  0.0 

कुछ अधिक संदर्भ: मेरा असली डेटा में, "id_col" कॉलम कुछ 30000 या उससे अधिक अनन्य मान हैं यहाँ मेरी छोटी कार्य है। इसका मतलब है कि डेटा फ्रेम 30000 बार कटा हुआ है। मुझे कल्पना है कि यह बाधा है।

उत्तर

5

'id_col' और फिर एक transform गुजर समारोह 'मिनट', यह एक श्रृंखला अपने मूल df के अनुरूप वापस आ जाएगी, ताकि आप एक नया स्तंभ के रूप में जोड़ सकते हैं पर एक groupby करें:

In [13]: 

df = pd.DataFrame({"id_col":[0, 0, 0, 1, 1, 1, 2, 2, 2], 
        "val_col":[0.1, 0.2, 0.3, 0.6, 0.4, 0.5, 0.2, 0.1, 0.0]}) 
df['offset'] = df.groupby('id_col').transform('min') 
df 
Out[13]: 
    id_col val_col offset 
0  0  0.1  0.1 
1  0  0.2  0.1 
2  0  0.3  0.1 
3  1  0.6  0.4 
4  1  0.4  0.4 
5  1  0.5  0.4 
6  2  0.2  0.0 
7  2  0.1  0.0 
8  2  0.0  0.0 

समय

In [15]: 

def apply_by_id_value(df, id_col="id_col", val_col="val_col", offset_col="offset", f=min): 
    for rid in set(df[id_col].values): 
     df.loc[df[id_col] == rid, offset_col] = f(df[df[id_col] == rid][val_col]) 
    return df 
%timeit apply_by_id_value(df) 
%timeit df.groupby('id_col').transform('min') 
100 loops, best of 3: 8.12 ms per loop 
100 loops, best of 3: 5.99 ms per loop 

तो groupby और transform इस डेटासेट पर तेजी से होता है, मैं इसे काफी अपने असली डाटासेट पर तेजी के रूप में यह बेहतर स्केल करेगा होने की उम्मीद।

एक 800,000 पंक्ति के लिए df मैं निम्नलिखित समय मिलता है:।

1 loops, best of 3: 611 ms per loop 
1 loops, best of 3: 438 ms per loop 
+1

GroupBy() को बदलने() समाधान में वास्तविक डेटा ;-) धन्यवाद तेजी से "केवल" चारों ओर 1,000 बार था इतना! मुझे पता था कि यह एपीआई में कहीं था। – nikosd

+0

मुझे लगता है कि यह डेटा वितरण पर निर्भर करता है, आपके डेटासेट पर केवल 3 अद्वितीय मान थे, इसलिए यह स्वयं को 100,000 बार लुकअप समय आनुपातिक रूप से तेज़ी से बना रहा, लेकिन आपके बहुत अधिक विविध डेटासेट पर गति तेज है, धन्यवाद मुझे गतिशील अंतर जानने दो – EdChum

संबंधित मुद्दे