2016-05-11 4 views
3

В R, можно использовать with(obj, a + b + c + d) вместо obj$a + obj$b + obj$c + obj$d, где obj может представлять собой list или data.frame.R с функцией в Python

Есть ли подобные функции для dict, pandas.Series, pandas.DataFrame в python?

+0

Кажется нет подобной функции в Python и большинство других языков программирования. (Http://stackoverflow.com/a/6061156/3054161) – su79eu7k

ответ

3

В некотором смысле, нет. Но есть много аналогичных альтернатив. Функция with R кажется довольно универсальной, поэтому в Python ее нужно заменить в каждом случае.

Вы можете использовать itemgetter() для простых коллекций:

In [1]: d = dict(a=1, b=2, c=3, d=4) 

In [2]: from operator import itemgetter 

In [3]: sum(itemgetter('a', 'b', 'c', 'd')(d)) 
Out[3]: 10 

Или attrgetter() для, опять же просто, объекты:

In [4]: from collections import namedtuple 

In [5]: from operator import attrgetter 

In [8]: sum(attrgetter('a', 'b', 'c', 'd')(
     namedtuple('sdf', 'a b c d')(1, 2, 3, 4))) 
Out[8]: 10 

панд DataFrame Поддержим прямого доступа определенных столбцов и применяющим операции над ними. Суммируя это простой пример, так как он имеет функцию как:

In [10]: df = pd.DataFrame({'A': range(10), 'B': range(10), 'C': range(10)}) 

In [21]: df[['A', 'B']].sum(axis=1) # row sums 
Out[21]: 
0  0 
1  2 
2  4 
3  6 
4  8 
5 10 
6 12 
7 14 
8 16 
9 18 
dtype: int64 

Там также DataFrame.eval, который находится ближе всего к тому, что вы после этого, я думаю:

Оценить выражение в контексте вызывающего экземпляра DataFrame.

In [9]: df.eval('(A + B) ** C') 
Out[9]: 
0    1 
1    2 
2    16 
3    216 
4   4096 
5   100000 
6   2985984 
7  105413504 
8  4294967296 
9 198359290368 
dtype: int64 
2

Не совсем. R и Python имеют довольно разные философии, когда дело доходит до такого рода вещей. В R можно написать функцию, которая анализирует весь синтаксис своих аргументов до их оценки, тогда как в Python это не так. Таким образом, в Python, что это невозможно:

df = pd.DataFrame({'a':[1,2],'b':[3,4],'c':[5,6],'d':[7,8]}) 
with(df, a + b + c) 

Однако, это работает:

sum(map(df.get, ('a','b','c'))) # gives Series([9,12]) 

Если вы хотите применить другие прикованных операции, вы могли бы реализовать поддержку что-то вроде этого:

def chain(op, df, name, *names): 
    res = df[name] 
    while names: 
     res = op(res, df[names[0]]) 
     names = names[1:] 
    return res 

Тогда вы можете сделать это:

from operator import div 
chain(div, df, 'a', 'b', 'c') 
Смежные вопросы