2016-04-01 19 views
1

Sagen wir, ich habe eine Tabelle, ss_prices, die eine Primärschlüsselspalte fund_code dass pandas behandelt als Index genannt hat:Pandas WHERE-Klausel für String-Index?

>>> arr = list(zip(['MM1', 'MM2', '3MM', '4AA'], range(1,5))) 
>>> cols = ['fund_code', 'values'] 
>>> ss_prices = pd.DataFrame(arr, columns=cols).set_index('fund_code') 
>>> ss_prices 
       values 
    fund_code 
    MM1  1 
    MM2  2 
    3MM  3 
    4AA  4 

ich diese Zeilen nur erhalten möchten, wo die Primärschlüssel beginnt mit ‚MM‘. In SQL kann ich tun:

select * from ss_prices 
where left(fund_code, 2) = 'MM' 

Aber in pandas es scheint, ich habe zu tun:

ss_prices[np.vectorize(lambda x: x[:2] == 'MM')(ss_prices.index.values)] 

Die pandas Syntax sicherlich verwirrend und weniger lesbar ist. Können Sie nicht einfach ein Tool wie pandasql verwenden, gibt es eine besser lesbare Möglichkeit, eine WHERE-Klausel zu erreichen?

Antwort

2

Sie DataFrame.filter verwenden können, auf dem Index zu filtern einen regulären Ausdruck:

In [5]: ss_prices 
Out[5]: 
    values 
MM1  1 
MM2  2 
3MM  3 
4AA  4 

In [6]: ss_prices.filter(regex='^MM', axis=0) 
Out[6]: 
    values 
MM1  1 
MM2  2 
+0

Schön !! Ich wünschte, SQL könnte solche regulären Ausdrücke machen. –

1

Sie können x.startswith("MM") verwenden (und Sie sollten, siehe PEP 8).

+0

Gefällt Ihnen das? 'ss_prices [np.vectorize (Lambda x: x.startswith ('MM')) (ss_prices.index.values)]'? Das ist ein wenig lesbarer, stimme ich zu, aber nicht viel. Ich habe auf etwas wie 'ss_prices.where (Lambda x: x.startswith (' MM '), Achse = 0) gehofft. ' –

+0

@MichaelCurrie Ja, das ist das Beste, was ich sagen kann. – cdonts

1

Versuchen df.index.to_series().str[:2]:

In [324]: df 
Out[324]: 
    a 
MMa 1 
MMb 2 
AAA 3 
BBB 4 

In [325]: df[df.index.to_series().str[:2] == 'MM'] 
Out[325]: 
    a 
MMa 1 
MMb 2 
1

Nur str.startswith verwenden, um direkt auf dem Index eine boolean Maske zurückzukehren:

In [27]: 
df[df.index.str.startswith('MM')] 

Out[27]: 
    a 
MMa 1 
MMb 2