在数据框中拆分和排序值

时间:2018-11-01 07:12:04

标签: python python-3.x pandas dataframe

例如,我有一个原始数据数据框:

      Data
0   XZ_1A-2A
1   XZ_3C
2   XZ_4B-5A
3   XZ_18A-20C

我想将其拆分(并删除XZ_

      Data        T1      T2
0   XZ_1A-2A      1A      2A
1   XZ_3C         3C
2   XZ_4B-5A      4B      5A
3   XZ_18A-20C   18A     20C

然后按数字排序

       T1      T2
0      2A      1A
1      3C
2      5A      4B
3     20C     18A     

感谢您的帮助。


[固定]

Update_1:
输入数据时:

      Data
0   XZ_17A-1A
1   XZ_5C
2   XZ_3A-28A

并使用

进行编译
df= (df['Data'].str.split('_|-',expand=True)[[1,2]]).rename(columns={1:'T2',2:'T1'}).fillna('')
asc=pd.DataFrame(np.sort(df[['T1','T2']],axis=1)) 
des= asc[asc.columns.values[::-1]]

我得到了输出

     1    0
0   1A  17A
1   5C  
2   3A  28A 

Update_2:
如果单行中有2个以上的项目(约1〜5),该如何排序?

       Data
0   XZ_17A-1A
1   XZ_5C
2   XZ_3A-28A
3   XZ_5A-19A-42C   
4   XZ_3A-28A-41A-42A

5 个答案:

答案 0 :(得分:5)

尝试一下:

df= df['Data'].str.split('_|-',expand=True)[[1,2]]

输出:

     1     2
0   1A    2A
1   3C  None
2   4B    5A
3  18A   20C

要在下面使用排序的值,

df= (df['Data'].str.split('_|-',expand=True)[[1,2]]).rename(columns={1:'T2',2:'T1'}).fillna('')
asc= df.apply(np.sort,axis=1)
asc=pd.DataFrame(np.sort(df[['T1','T2']],axis=1)) #alternative way
des= asc[asc.columns.values[::-1]]
print des

输出:

    T1    T2
0   2A    1A
1   3C     
2   5A    4B
3  20C   18A

说明:

a)清理数据后,使用np.sort,axis=1根据行值通过升序对数据框进行排序

b)要获得降序,请反转列顺序。

c)使用fillna来获得准确的结果。

编辑:

df= (df['Data'].str.split('_|-',expand=True)[[1,2]]).rename(columns={1:'T2',2:'T1'})

df['n1']=df['T1'].str.extract('(\d+)').astype(float)
df['n2']=df['T2'].str.extract('(\d+)').astype(float)
res=pd.DataFrame()
res['result'] =df.apply(lambda x: [x['T1'],x['T2']] if x['n1']>x['n2'] else [x['T2'],x['T1']],axis=1).fillna('')
res[['T1','T2']]=res['result'].astype(str).str.replace("\[|\]|'",'').str.split(',',expand=True)

输出:

       result   T1     T2
0   [17A, 1A]  17A     1A
1  [5C, None]   5C      
2   [28A, 3A]  28A     3A

有关多列,请参见下面的示例,

df= (df['Data'].str.split('_|-',expand=True)[[1,2]]).rename(columns={1:'T2',2:'T1'}).fillna('')
df['n1']=df['T1'].str.extract('(\d+)').astype(float)
df['n2']=df['T2'].str.extract('(\d+)').astype(float)
df['n3']=[432,4,15]
res=pd.DataFrame()
res['result'] =df.apply(lambda x: sorted([x['n1'],x['n2'],x['n3']],reverse=True),axis=1)
res[['T1','T2','T3']]=res['result'].astype(str).str.replace("\[|\]|'",'').str.split(',',expand=True)

输入:

    T2   T1    n1    n2   n3
0  17A   1A   1.0  17.0  432
1   5C        NaN   5.0    4
2   3A  28A  28.0   3.0   15

输出:

             result    T1     T2    T3
0  [432, 17.0, 1.0]   432   17.0   1.0
1     [nan, 5.0, 4]   nan    5.0     4
2   [28.0, 15, 3.0]  28.0     15   3.0

答案 1 :(得分:2)

尝试..

>>> df1
         Data
0    XZ_1A-2A
1       XZ_3C
2    XZ_4B-5A
3  XZ_18A-20C


>>> newdf = df1['Data'].str.split('_|-', expand=True)[[1,2]]

使用rename函数替换列名称,如下所示。

>>> newdf.rename(columns={1: 'T1', 2: 'T2'}, inplace=True)
>>> newdf
    T1    T2
0   1A    2A
1   3C  None
2   4B    5A
3  18A   20C

但是,如果您还想将None替换为空字符串,则可以如下所示:

>>> newdf['T2'].fillna(value='', inplace=True)
>>> newdf
    T1   T2
0   1A   2A
1   3C
2   4B   5A
3  18A  20C

答案 2 :(得分:1)

执行以下步骤:

  1. 使用.ix(num)获取行num的值。
  2. 使用.split('-')
  3. 在连字符上拆分值
  4. 添加一条if语句以检查数组中的元素数并相应地创建数据框。

希望这有所帮助。

答案 3 :(得分:1)

最简单的方法是:

df1 = data["Data"].str.split("-", n = 1, expand = True)
output:

      0        1
0     XZ_1A    2A
1     XZ_3C    None
2     XZ_4B    5A
3     XZ_18A   20C

df2 = df1[0].str.split("_", n = 1, expand = True) 
output : 

   0    1
0  XZ   1A
1  XZ   3C
2  XZ   4B
3  XZ  18A


data["T1"]= df2[1]
data["T2"]= df1[1]

最后您得到了:

         Data   T1    T2
0    XZ_1A-2A   1A    2A
1       XZ_3C   3C  None
2    XZ_4B-5A   4B    5A
3  XZ_18A-20C  18A   20C

答案 4 :(得分:0)

df = pd.DataFrame(['XZ_17A-1A','XZ_5C','XZ_3A-28A'],columns=['a'])<br>
df1 = df['a'].str.split('_|-',expand=True).loc[:,1:2]<br>
df1[3],df1[4] = df1[1].str.extract('([0-9]*)').astype('float'),df1[2].str.extract('([0-9]*)').astype('float')<br>
df2 = df1.sort_values(by=[3,4],ascending=True,axis=0)<br>
df2.drop([3,4],axis=1,inplace=True)<br>
df2.columns=['T1','T2']