该文档说明如何将GROUPBY对象在同一时间使用的字典与输出列名作为关键字应用多个功能:
In [563]: grouped['D'].agg({'result1' : np.sum,
.....: 'result2' : np.mean})
.....:
Out[563]:
result2 result1
A
bar -0.579846 -1.739537
foo -0.280588 -1.402938
Run Code Online (Sandbox Code Playgroud)
但是,这仅适用于Series groupby对象.当dict类似地传递给一个由DataFrame组成的组时,它希望键是该函数将应用于的列名.
我想要做的是将多个函数应用于多个列(但某些列将被多次操作).此外,某些函数将依赖于groupby对象中的其他列(如sumif函数).我目前的解决方案是逐列,并执行类似上面的代码,使用lambdas作为依赖于其他行的函数.但这需要很长时间,(我认为迭代一个groupby对象需要很长时间).我将不得不改变它,以便我在一次运行中遍历整个groupby对象,但我想知道在pandas中是否有一种内置的方式可以做得有点干净.
例如,我尝试过类似的东西
grouped.agg({'C_sum' : lambda x: x['C'].sum(),
'C_std': lambda x: x['C'].std(),
'D_sum' : lambda x: x['D'].sum()},
'D_sumifC3': lambda x: x['D'][x['C'] == 3].sum(), ...)
Run Code Online (Sandbox Code Playgroud)
但正如预期的那样,我得到一个KeyError(因为如果agg从DataFrame中调用键,则键必须是一个列).
有没有内置的方法来做我想做的事情,或者可能添加这个功能的可能性,还是我只需要手动迭代组合?
谢谢
如何通过密钥访问groupby对象中的相应groupby数据帧?使用以下groupby:
rand = np.random.RandomState(1)
df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
'B': rand.randn(6),
'C': rand.randint(0, 20, 6)})
gb = df.groupby(['A'])
Run Code Online (Sandbox Code Playgroud)
我可以遍历它以获取密钥和组:
In [11]: for k, gp in gb:
print 'key=' + str(k)
print gp
key=bar
A B C
1 bar -0.611756 18
3 bar -1.072969 10
5 bar -2.301539 18
key=foo
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
Run Code Online (Sandbox Code Playgroud)
我希望能够做类似的事情
In [12]: gb['foo']
Out[12]:
A B C
0 foo 1.624345 5
2 foo …Run Code Online (Sandbox Code Playgroud) 有没有内置的方法可以在不知道行的长度的情况下read_csv只读取n文件的第一行?我有一个大文件,需要很长时间才能阅读,偶尔只想使用第一行,比方说20行来获取它的样本(并且不想加载完整的东西并占据它的头部).
如果我知道我可以做的事情的总行数,footer_lines = total_lines - n并将其传递给skipfooter关键字arg.我目前的解决方案是手动抓取npython和StringIO 的第一行到pandas:
import pandas as pd
from StringIO import StringIO
n = 20
with open('big_file.csv', 'r') as f:
head = ''.join(f.readlines(n))
df = pd.read_csv(StringIO(head))
Run Code Online (Sandbox Code Playgroud)
它并没有那么糟糕,但有一种更简洁,"pandasic"(?)方式用关键字或其他方式做到这一点?
给出以下数据帧
In [31]: rand = np.random.RandomState(1)
df = pd.DataFrame({'A': ['foo', 'bar', 'baz'] * 2,
'B': rand.randn(6),
'C': rand.rand(6) > .5})
In [32]: df
Out[32]: A B C
0 foo 1.624345 False
1 bar -0.611756 True
2 baz -0.528172 False
3 foo -1.072969 True
4 bar 0.865408 False
5 baz -2.301539 True
Run Code Online (Sandbox Code Playgroud)
我想在group(A)中按聚合的总和B,然后按C(未聚合)中的值对其进行排序.所以基本上得到A组的顺序
In [28]: df.groupby('A').sum().sort('B')
Out[28]: B C
A
baz -2.829710 1
bar 0.253651 1
foo 0.551377 1
Run Code Online (Sandbox Code Playgroud)
然后通过True/False,这样它最终看起来像这样:
In [30]: df.ix[[5, …Run Code Online (Sandbox Code Playgroud) [免责声明:可能有更多pythonic方式做我想做的事情,但我想知道python的范围如何在这里工作]
我正在尝试找到一种方法来制作一个装饰器,它可以将名称注入到另一个函数的范围内(这样名称不会泄漏到装饰器的范围之外).例如,如果我有一个函数说要打印一个名为var尚未定义的变量,我想在调用它的装饰器中定义它.这是一个打破的例子:
c = 'Message'
def decorator_factory(value):
def msg_decorator(f):
def inner_dec(*args, **kwargs):
var = value
res = f(*args, **kwargs)
return res
return inner_dec
return msg_decorator
@decorator_factory(c)
def msg_printer():
print var
msg_printer()
Run Code Online (Sandbox Code Playgroud)
我想要打印" Message",但它给出了:
NameError: global name 'var' is not defined
Run Code Online (Sandbox Code Playgroud)
回溯甚至指向wher var定义:
<ipython-input-25-34b84bee70dc> in inner_dec(*args, **kwargs)
8 def inner_dec(*args, **kwargs):
9 var = value
---> 10 res = f(*args, **kwargs)
11 return res
12 return inner_dec
Run Code Online (Sandbox Code Playgroud)
所以我不明白为什么找不到var.
有没有办法做这样的事情?
传递int和lambda: 0作为参数之间有什么区别吗?或者之间list和lambda: []?
看起来他们做同样的事情:
from collections import defaultdict
dint1 = defaultdict(lambda: 0)
dint2 = defaultdict(int)
dlist1 = defaultdict(lambda: [])
dlist2 = defaultdict(list)
for ch in 'abracadabra':
dint1[ch] += 1
dint2[ch] += 1
dlist1[ch].append(1)
dlist2[ch].append(1)
print dint1.items()
print dint2.items()
print dlist1.items()
print dlist2.items()
## -- Output: --
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
[('a', [1, 1, 1, 1, 1]), …Run Code Online (Sandbox Code Playgroud) 正如这里提到的,你可以使用star解压缩未知数量的变量(比如在函数中),但只能在python 3中:
>>> a, *b = (1, 2, 3)
>>> b
[2, 3]
>>> a, *b = (1,)
>>> b
[]
Run Code Online (Sandbox Code Playgroud)
在python 2.7中,我能想到的最好的是(并不可怕,但很烦人):
c = (1, 2, 3)
a, b = c[0], c[1:] if len(c) > 1 else []
Run Code Online (Sandbox Code Playgroud)
有没有办法从__future__像分区导入它,或者我需要自己的函数在python 2.7中进行未知长度的解包?
在终端,它的工作原理
python -c "import sys; print(sys.version)"
Run Code Online (Sandbox Code Playgroud)
但是做
:python -c "import sys; print(sys.version)"
Run Code Online (Sandbox Code Playgroud)
在vim中抛出一个SyntaxError.
有没有办法让defaultdict默认返回密钥?或者一些具有同等行为的数据结构?即,在初始化字典后d,
>>> d['a'] = 1
>>> d['a']
1
>>> d['b']
'b'
>>> d['c']
'c'
Run Code Online (Sandbox Code Playgroud)
我只看到默认字典采用不带参数的函数,所以我不确定除了创建一种新的字典之外是否还有其他解决方案.
对于数据帧
In [2]: df = pd.DataFrame({'Name': ['foo', 'bar'] * 3,
...: 'Rank': np.random.randint(0,3,6),
...: 'Val': np.random.rand(6)})
...: df
Out[2]:
Name Rank Val
0 foo 0 0.299397
1 bar 0 0.909228
2 foo 0 0.517700
3 bar 0 0.929863
4 foo 1 0.209324
5 bar 2 0.381515
Run Code Online (Sandbox Code Playgroud)
我对按名称和等级分组并可能获得聚合值感兴趣
In [3]: group = df.groupby(['Name', 'Rank'])
In [4]: agg = group.agg(sum)
In [5]: agg
Out[5]:
Val
Name Rank
bar 0 1.839091
2 0.381515
foo 0 0.817097
1 0.209324
Run Code Online (Sandbox Code Playgroud)
但是我希望在原始字段中df包含该行的组号,例如
In [13]: …Run Code Online (Sandbox Code Playgroud) python ×10
pandas ×5
group-by ×4
dataframe ×3
defaultdict ×2
closures ×1
collections ×1
csv ×1
decorator ×1
dictionary ×1
scope ×1
sorting ×1
vim ×1