如何在Pandas中打开一系列元组?

mwa*_*kom 30 python pandas

有时我在使用Pandas时会得到一系列元组/列表.例如,当执行group-by并传递具有多个返回值的函数时,这很常见:

import numpy as np
from scipy import stats
df = pd.DataFrame(dict(x=np.random.randn(100),
                       y=np.repeat(list("abcd"), 25)))
out = df.groupby("y").x.apply(stats.ttest_1samp, 0)
print out

y
a       (1.3066417476, 0.203717485506)
b    (0.0801133382517, 0.936811414675)
c      (1.55784329113, 0.132360504653)
d     (0.267999459642, 0.790989680709)
dtype: object
Run Code Online (Sandbox Code Playgroud)

"解压缩"这个结构的正确方法是什么,以便我得到一个包含两列的DataFrame?

一个相关的问题是我如何将这个结构或结果数据框解包为两个系列/数组对象.这几乎有效:

t, p = zip(*out)
Run Code Online (Sandbox Code Playgroud)

但它t

 (array(1.3066417475999257),
 array(0.08011333825171714),
 array(1.557843291126335),
 array(0.267999459641651))
Run Code Online (Sandbox Code Playgroud)

一个人需要采取额外的步骤来挤压它.

Sir*_* S. 28

也许这是最直接的(我猜是最pythonic):

out.apply(pd.Series)
Run Code Online (Sandbox Code Playgroud)

如果你想将列重命名为更有意义的东西,那么:

out.columns=['Kstats','Pvalue']
Run Code Online (Sandbox Code Playgroud)

如果您不想要索引的默认名称:

out.index.name=None
Run Code Online (Sandbox Code Playgroud)

  • 切换正确的答案,因为我同意它是最干净的.实际上也可以用`out.apply(pd.Series,index = ["stat,"p"])一次性获得正确的列名. (4认同)
  • 根据文档,如果“func”返回一个 Series,“Series.apply(func)”将返回一个 DataFrame。`out.apply(pd.Series, index=['stat', 'p'])` 会将每个元组转换为具有 2 个值的 Series,并且由于 `out` 已经有一个索引,因此新的 Series 索引将成为列名字 (2认同)

beh*_*uri 13

也许:

>>> pd.DataFrame(out.tolist(), columns=['out-1','out-2'], index=out.index)
                  out-1     out-2
y                                
a   -1.9153853424536496  0.067433
b     1.277561889173181  0.213624
c  0.062021492729736116  0.951059
d    0.3036745009819999  0.763993

[4 rows x 2 columns]
Run Code Online (Sandbox Code Playgroud)


CT *_*Zhu 11

我相信你想要这个:

df=pd.DataFrame(out.tolist())
df.columns=['KS-stat', 'P-value']
Run Code Online (Sandbox Code Playgroud)

结果:

           KS-stat   P-value
0   -2.12978778869  0.043643
1    3.50655433879  0.001813
2    -1.2221274198  0.233527
3  -0.977154419818  0.338240
Run Code Online (Sandbox Code Playgroud)

  • +1:这比`out.apply(pd.Series)`快2倍.在我的情况下,元组是成对的字符串(我有4000个字符串),它快400倍... (2认同)

Jer*_*y Z 5

我遇到过类似的问题。我发现的两种解决方法正是@CT ZHU 和@Siraj S 的答案。

以下是您可能感兴趣的补充信息: 我比较了 2 种方式,发现 @CT ZHU 的方式在输入大小增加时执行得更快。

例子:

#Python 3
import time
from statistics import mean
df_a = pd.DataFrame({'a':range(1000),'b':range(1000)})

#function to test
def func1(x):
    c = str(x)*3
    d = int(x)+100
    return c,d

# Siraj S's way
time_difference = []
for i in range(100):
    start = time.time()
    df_b = df_a['b'].apply(lambda x: func1(x)).apply(pd.Series)
    end = time.time()
    time_difference.append(end-start)

print(mean(time_difference))    
# 0.14907703161239624

# CT ZHU's way
time_difference = []
for i in range(100):
    start = time.time()
    df_b = pd.DataFrame(df_a['b'].apply(lambda x: func1(x)).tolist())
    end = time.time()
    time_difference.append(end-start)    

print(mean(time_difference)) 
# 0.0014058423042297363
Run Code Online (Sandbox Code Playgroud)

PS:请原谅我丑陋的代码。