2016-07-06 4 views
0

У меня есть два списка:Панды Dataframe найти и заменить

single = ['A','B'] 
double = ['AA','BB'] 

данные, хранящиеся в dataframe df:

 0 1 2 3 
0 All 1 AA Yes 
1 A 2 All No 

, где все средства ['A','B'] в колонке 0 и означает в колонке 2 ['AA','BB'], я хочу получить следующий информационный кадр df2

0 1 2 3 
0 A 1 AA Yes 
1 B 1 AA Yes 
2 A 2 AA No 
3 A 2 BB No 

и порядок индекса строки не имеет значения. Я сейчас делаю:

single = ['A','B'] 
double = ['AA','BB'] 
df=pd.DataFrame([['All',1,'AA','Yes'],['A',2,'All','No']]) 

index = [] 
for i in range(len(df)): 
    if df.loc[i,0] == 'All': 
     index.append(i) 
     for j in single: 
      df.loc[len(df),:] = df.loc[i,:] 
      df.loc[len(df)-1,0] = j 
df = df.drop(index).reset_index(drop=True) 

index = [] 
for i in range(len(df)): 
    if df.loc[i,2] == 'All': 
     index.append(i) 
     for j in double: 
      df.loc[len(df),:] = df.loc[i,:] 
      df.loc[len(df)-1,2] = j 
df2 = df.drop(index).reset_index(drop=True) 
print df2 

Он сначала добавляет две строки для представления «Все» в столбце 0 и удаляет эту строку. Затем для «Все» в колонке 2.

Любой более простой способ сделать это «найти и заменить»?

ответ

2
import pandas as pd 

single = ['A','B'] 
double = ['AA','BB'] 
df = pd.DataFrame([['All',1,'AA','Yes'],['A',2,'All','No']]) 

first = pd.DataFrame([x for item in single 
         for x in [('All', item), (item, item)]], columns=[0, 'first']) 
third = pd.DataFrame([x for item in double 
         for x in [('All', item), (item, item)]], columns=[2, 'third']) 

result = pd.merge(pd.merge(df, first, how='left'), third, how='left') 
result = result.drop([0, 2], axis=1) 
result = result.rename(columns={'first':0, 'third':2}) 
result = result.sortlevel(axis=1) 

дает

0 1 2 3 
0 A 1 AA Yes 
1 B 1 AA Yes 
2 A 2 AA No 
3 A 2 BB No 

Основная идея заключается в том, чтобы подготовить две вспомогательные DataFrames:

first = pd.DataFrame([x for item in single 
         for x in [('All', item), (item, item)]], columns=[0, 'first']) 
#  0 first 
# 0 All  A 
# 1 A  A 
# 2 All  B 
# 3 B  B 

third = pd.DataFrame([x for item in double 
         for x in [('All', item), (item, item)]], columns=[2, 'third']) 
#  2 third 
# 0 All AA 
# 1 AA AA 
# 2 All BB 
# 3 BB BB 

Тогда искомое DataFrame является результатом слияния df с first и third:

result = pd.merge(pd.merge(df, first, how='left'), third, how='left') 
#  0 1 2 3 first third 
# 0 All 1 AA Yes  A AA 
# 1 All 1 AA Yes  B AA 
# 2 A 2 All No  A AA 
# 3 A 2 All No  A BB 

Наконец, падение 0 и 2 колонки, и заменить их с first и third колонок:

result = result.drop([0, 2], axis=1) 
result = result.rename(columns={'first':0, 'third':2}) 
result = result.sortlevel(axis=1) 
# 0 1 2 3 
# 0 A 1 AA Yes 
# 1 B 1 AA Yes 
# 2 A 2 AA No 
# 3 A 2 BB No 
+0

Спасибо. Он работает лучше. – ilovecp3

Смежные вопросы