Сценарий R для кода Python

HowdyDude спросил: 13 июня 2018 в 07:09 в: python

Я начинаю копаться глубже в Python, и мне трудно преобразовать некоторые из моих R-скриптов в Python. У меня есть функция, определенная в R:

Shft_Rw <- function(x) { for (row in 1:nrow(x))
{
  new_row = x[row , c(which(!is.na(x[row, ])), which(is.na( x[row, ])))]
  colnames(new_row) = colnames(x)
  x[row, ] = new_row
}
  return(x)  
}

Что по существу принимает ведущие NA каждой строки в фрейме данных и помещает их в конец строки, т. Е.

import pandas as pd
import numpy as np
df =pd.DataFrame({'a':[np.nan,np.nan,3],'b':[3,np.nan,5],'c':[3, 4,5]})df
Out[156]: 
     a    b  c
0  NaN  3.0  3
1  NaN  NaN  4
2  3.0  5.0  5

превращается в:

df2 =pd.DataFrame({'a':[3,4,3],'b':[3,np.nan,5],'c':[np.nan, np.nan,5]})
df2
Out[157]: 
   a    b    c
0  3  3.0  NaN
1  4  NaN  NaN
2  3  5.0  5.0

Пока у меня есть:

def Shft_Rw(x):
    for row in np.arange(0,x.shape[0]):
        new_row = x.iloc[row,[np.where(pd.notnull(x.iloc[row])),np.where(pd.isnull(df.iloc[row]))]]

Но бросание ошибок. Используя пример df выше, я могу получить индекс строки, используя iloc и позиции столбца, где он имеет значение null / not null (с использованием where ()), но не может совместить их (попробовал множество вариантов с большим количеством скобок и т. Д.).

df.iloc[1]
Out[170]: 
a    NaN
b    NaN
c    4.0np.where(pd.isnull(df.iloc[1]))
In[167] :  np.where(pd.isnull(df.iloc[1]))
Out[167]: (array([0, 1], dtype=int64),)df.iloc[1,np.where(pd.notnull(df.iloc[1]))]

Любой, кто может помочь реплицировать функцию AND / OR, показывает более эффективный способ решения проблемы?

Спасибо!

1 ответ

Есть решение
jezrael ответил: 14 июня 2018 в 10:59

Используйте apply с dropna:

df1 = df.apply(lambda x: pd.Series(x.dropna().values), axis=1)
df1.columns = df.columns
print (df1)
     a    b    c
0  3.0  3.0  NaN
1  4.0  NaN  NaN
2  3.0  5.0  5.0

Если производительность важна, я предлагаю использовать этот идеальный justify function :

arr = justify(df.values, invalid_val=np.nan, axis=1, side='left')
df1 = pd.DataFrame(arr, index=df.index, columns=df.columns)
print (df1)
     a    b    c
0  3.0  3.0  NaN
1  4.0  NaN  NaN
2  3.0  5.0  5.0
HowdyDude ответил: 14 июня 2018 в 12:51
Потрясающие! Это сработало - просто нужно было сделать один промежуточный шаг. По-видимому, использование groupby изменяет nan на 0, поэтому просто нужно было сделать .replace (0, np.nan) перед вашим решением. Благодаря!
jezrael ответил: 14 июня 2018 в 12:52
@HowdyDude - Добро пожаловать! Благодарим вас за принятие. Вы также можете подняться - нажмите на маленький треугольник выше 0 выше принятой метки. Благодарю.
HowdyDude ответил: 14 июня 2018 в 01:04
С другой стороны, вероятно, это был .aggregate (np.sum), который преобразовал nan
jezrael ответил: 14 июня 2018 в 01:09
@HowdyDude Я думаю, что можно использовать .sum(min_count=1) вместо .aggregate(np.sum), chek this

Дополнительное видео по вопросу: Сценарий R для кода Python

Intro to Data Analysis / Visualization with Python, Matplotlib and Pandas | Matplotlib Tutorial

17.Python для Начинающих - Классы Часть1

// Злокодинг с Python #3 // Вирус //