如何更改列值并使用pandas排序?

时间:2016-05-02 18:53:28

标签: python pandas dataframe

我有以下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
    ....

显然,cat1的顺序不正确,因为cat2应该在cat1之后,而不是在cat19之后。

可以使用哪些方法来纠正这个问题?

我的想法是重新标记每个单位数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'})

似乎必须将索引更改为cat列,然后使用上述方法并进行排序。

然而,我仍然打字太多了。完成此任务的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以使用正则表达式提取数字(\d+表示一个或多个数字),使用zfill将其填零,然后将cat添加回结果。我已将3用于zfill,因此1变为001。您可以根据需要进行调整。

我还创建了一个蒙版,仅将其应用于具有数字的行。

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

答案 1 :(得分: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