2016-05-02 5 views
1

私は以下のpandas DataFrameを持っています。明らかに列の値を変更してパンダで並べ替える方法は?

import pandas as pd 
df = pd.read_csv('filename.csv') 

print(df) 

    cat  A   B   C 
0  cat1 0.787575 0.159330 0.053095 
1  cat10 0.770698 0.169487 0.059815 
2  cat11 0.792689 0.152043 0.055268 
3  cat12 0.785066 0.160361 0.054573 
4  cat13 0.795455 0.150464 0.054081 
5  cat14 0.794873 0.150700 0.054426 
.. .... 
8  cat19 0.811585 0.140207 0.048208 
9  cat2 0.797202 0.152033 0.050765 
10 cat20 0.801607 0.145137 0.053256 
11 cat21 0.792689 0.152043 0.055268 
    .... 

cat2はないcat19後、cat1後に行く必要があるため、cat1は、不適切な順序です。

これを修正するためにどのような方法を使用できますか?

私の考えは、各一桁catのラベルを付け直して、.sort()でソートすることです。しかし、これを行う私の方法は動作しません。

df = df.rename(index={'cat1': 'cat01'}) 
df = df.rename(index={'cat2': 'cat02'}) 
df = df.rename(index={'cat3': 'cat03'}) 
... 
df = df.rename(index={'cat9': 'cat09'}) 

1つは、上記の方法、および並べ替えを使用し、その後、cat列にインデックスを変更する必要があります表示されます。

しかし、私はまだ入力しすぎています。これを達成する最良の方法は何ですか?

答えて

2

あなたはzfillゼロにパッドそれらを使用し、数字を(\d+が1桁以上を意味する)を抽出する正規表現式を使用することができ、結果にcatを追加してください。私はに3を使用しましたので、1001になります。これをあなたのニーズに合わせて調整することができます。

私はまた、これを桁のある行にのみ適用するためのマスクを作成しました。

np.random.seed(0) 
df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC')) 
df['cat'] = ['catZ', 'cat10', 'cat11', 'cat12', 'cat13'] 

digit_str = df.cat.str.extract(r'(\d+)').str.zfill(3) 
mask = digit_str.notnull() 
df.loc[mask, 'cat'] = 'cat' + digit_str[mask] 

>>> df 
      A   B   C  cat 
0 1.764052 0.400157 0.978738 catZ 
1 2.240893 1.867558 -0.977278 cat010 
2 0.950088 -0.151357 -0.103219 cat011 
3 0.410599 0.144044 1.454274 cat012 
4 0.761038 0.121675 0.443863 cat013 
+0

'catZ'という名前の猫が1つあります。残念ながら、上記の方法では、これはNaNに変換されます。 – ShanZhengYang

+0

新しい編集では、 'catZ'を' cat0'に消去します。 – ShanZhengYang

+0

@ShanZhengYang上記のサンプルでは動作しますが、catZの 'cat0'という結果はどうなると思いますか? – Alexander

1

私はあなたがzfillを使用することができると思う:

print df.cat.str.len() == 4 
0  True 
1  False 
2  False 
3  False 
4  False 
5  False 
8  False 
9  True 
10 False 
11 False 
Name: cat, dtype: bool 

print df.cat.str[-1] 
0  1 
1  0 
2  1 
3  2 
4  3 
5  4 
8  9 
9  2 
10 0 
11 1 
Name: cat, dtype: object 
df.loc[(df.cat.str.len() == 4) & 
     (df.cat != 'catZ'), 'cat'] = 'cat' + df.cat.str[-1].str.zfill(2) 
print df 
     cat   A   B   C 
0 cat01 0.787575 0.159330 0.053095 
1 cat10 0.770698 0.169487 0.059815 
2 cat11 0.792689 0.152043 0.055268 
3 cat12 0.785066 0.160361 0.054573 
4 cat13 0.795455 0.150464 0.054081 
5 cat14 0.794873 0.150700 0.054426 
8 cat19 0.811585 0.140207 0.048208 
9 cat02 0.797202 0.152033 0.050765 
10 cat20 0.801607 0.145137 0.053256 
11 catZ 0.792689 0.152043 0.055268 
+0

「catZ」という名前の猫が1つあります。残念ながら、上記の方法では、これは 'cat0Z'に変換されます。私は最初に「cat」の後に数字が続くかどうかをチェックするだろうと思いますか? – ShanZhengYang

+0

私は最初に文字列の 'length'をチェックし、ifが' 4'で 'catZ'ではない' str.zfill'を適用します – jezrael

関連する問題