Разделить и отсортировать значение в кадре данных - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть необработанный кадр данных, например:

      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     

Спасибо за вашу помощь.


[FIXED]

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:
Если в строке simgle более 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 голосов
/ 01 ноября 2018
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']
0 голосов
/ 01 ноября 2018

попробовать ..

>>> 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
0 голосов
/ 01 ноября 2018

Попробуйте это:

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) Чтобы получить нисходящий порядок, измените порядок столбцов.

в) используйте fillna для получения точного результата.

Edit:

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
0 голосов
/ 01 ноября 2018

Самый простой способ:

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
0 голосов
/ 01 ноября 2018

Выполните следующие шаги:

  1. Используйте .ix(num), чтобы получить значение в строке num.
  2. Разбить значение на дефис с помощью .split('-')
  3. Добавьте оператор if, чтобы проверить количество элементов в массиве и создать соответствующий фрейм данных.

Надеюсь, это помогло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...