python: разделит фрейм данных на два [дубликата]

1
задан Dance Party 17 March 2016 в 06:23
поделиться

3 ответа

Выполнение str.split, за которым следует apply, возвращающее pd.Series, создаст новые столбцы:

>>> df.B.str.split('>').apply(
    lambda l: pd.Series({'C': l[0], 'D': l[1][1: ]}) if len(l) == 2 else \
        pd.Series({'C': '', 'D': l[0]}))
    C   D
0   Y   abcd
1       abcd
2       efgh
3   Y   efgh

Таким образом, вы можете concat это применить к DataFrame и del исходная колонка:

df = pd.concat([df, df.B.str.split('>').apply(
    lambda l: pd.Series({'C': l[0], 'D': l[1][1: ]}) if len(l) == 2 else \
        pd.Series({'C': '', 'D': l[0]}))],
    axis=1)
del df['B']
>>> df
    A   C   D
0   a   Y   abcd
1   b       abcd
2   c       efgh
3   d   Y   efgh
2
ответ дан Ami Tavory 21 August 2018 в 09:46
поделиться
  • 1
    Это работало нормально, но мне просто пришлось изменить оба экземпляра от [1:] до [0:], чтобы по какой-то причине (с моими реальными данными) не обрезать первый символ каждого значения для столбца D. Благодаря! – Dance Party 18 March 2016 в 00:50

Я бы использовал один лайнер:

df['B'].str.split('>`').apply(lambda x: pd.Series(['']*(2-len(x)) + x))

#   0     1
#0  Y  abcd
#1     abcd
#2     efgh
#3  Y  efgh
1
ответ дан Colonel Beauvel 21 August 2018 в 09:46
поделиться

Вы можете использовать str.extract с fillna , последним столбцом падения B на drop :

df[['C','D']] = df['B'].str.extract('(.*)>`(.*)', expand=True)
df['D'] = df['D'].fillna(df['B'])
df['C'] = df['C'].fillna('')
df = df.drop('B', axis=1)

print df

   A  C     D
0  a  Y  abcd
1  b     abcd
2  c     efgh
3  d  Y  efgh

Следующее решение использует str.split с mask и numpy.where :

df[['C','D']] =  df['B'].str.split('>`', expand=True) 
mask = pd.notnull(df['D'])
df['D'] = df['D'].fillna(df['C'])
df['C'] = np.where(mask, df['C'], '')
df = df.drop('B', axis=1) 

Сроки:

В больших DataFrame решениях extract 100 раз быстрее, в малых 1.5 раз:

len(df)=4:

In [438]: %timeit a(df)
100 loops, best of 3: 2.96 ms per loop

In [439]: %timeit b(df1)
1000 loops, best of 3: 1.86 ms per loop

In [440]: %timeit c(df2)
The slowest run took 4.44 times longer than the fastest. This could mean that an intermediate result is being cached 
1000 loops, best of 3: 1.89 ms per loop

In [441]: %timeit d(df3)
The slowest run took 4.62 times longer than the fastest. This could mean that an intermediate result is being cached 
1000 loops, best of 3: 1.82 ms per loop

len(df)=4k:

In [443]: %timeit a(df)
1 loops, best of 3: 799 ms per loop

In [444]: %timeit b(df1)
The slowest run took 4.19 times longer than the fastest. This could mean that an intermediate result is being cached 
100 loops, best of 3: 7.37 ms per loop

In [445]: %timeit c(df2)
1 loops, best of 3: 552 ms per loop

In [446]: %timeit d(df3)
100 loops, best of 3: 9.55 ms per loop

Код:

import pandas as pd
df = pd.DataFrame({
       'A' : ['a', 'b','c', 'd'],
       'B' : ['Y>`abcd', 'abcd','efgh', 'Y>`efgh']
    })
#for test 4k    
df = pd.concat([df]*1000).reset_index(drop=True)
df1,df2,df3 = df.copy(),df.copy(),df.copy()

def b(df):
    df[['C','D']] = df['B'].str.extract('(.*)>`(.*)', expand=True)
    df['D'] = df['D'].fillna(df['B'])
    df['C'] = df['C'].fillna('')
    df = df.drop('B', axis=1)
    return df

def a(df):
    df = pd.concat([df, df.B.str.split('>').apply(
    lambda l: pd.Series({'C': l[0], 'D': l[1][1: ]}) if len(l) == 2 else \
        pd.Series({'C': '', 'D': l[0]}))], axis=1)
    del df['B']
    return df

def c(df):
    df[['C','D']] = df['B'].str.split('>`').apply(lambda x: pd.Series(['']*(2-len(x)) + x))
    df = df.drop('B', axis=1)    
    return df   

def d(df):
    df[['C','D']] =  df['B'].str.split('>`', expand=True) 
    mask = pd.notnull(df['D'])
    df['D'] = df['D'].fillna(df['C'])
    df['C'] = np.where(mask, df['C'], '')
    df = df.drop('B', axis=1) 
    return df  
2
ответ дан jezrael 21 August 2018 в 09:46
поделиться
  • 1
    Спасибо за тщательное рассмотрение этой темы! После применения метода extract эта ошибка была выбрана: TypeError: extract () получил неожиданный аргумент ключевого слова 'expand' – Dance Party 18 March 2016 в 00:09
  • 2
    Вы должны обновить версию pandas до 0.18.0, тогда она работает очень хорошо. – jezrael 18 March 2016 в 06:11
Другие вопросы по тегам:

Похожие вопросы: