在pandas DataFrame中的列上的.str.split()操作之后获取最后一个"列"

Ric*_*ron 50 python string split pandas

我在pandas DataFrame中有一个列,我想在一个空格上拆分.拆分很简单DataFrame.str.split(' '),但我不能从最后一个条目创建一个新列.当我.str.split()在列中获得数组列表时,我不知道如何操作它来为我的DataFrame获取新列.

这是一个例子.该列中的每个条目都包含"符号数据价格",我想分拆价格(最终在一半的情况下删除"p"...或"c").

import pandas as pd
temp = pd.DataFrame({'ticker' : ['spx 5/25/2001 p500', 'spx 5/25/2001 p600', 'spx 5/25/2001 p700']})
temp2 = temp.ticker.str.split(' ')
Run Code Online (Sandbox Code Playgroud)

产量

0    ['spx', '5/25/2001', 'p500']
1    ['spx', '5/25/2001', 'p600']
2    ['spx', '5/25/2001', 'p700']
Run Code Online (Sandbox Code Playgroud)

temp2[0]只是给出一个列表条目的数组并temp2[:][-1]失败.如何将每个数组中的最后一个条目转换为新列?谢谢!

Wes*_*ney 102

做这个:

In [43]: temp2.str[-1]
Out[43]: 
0    p500
1    p600
2    p700
Name: ticker
Run Code Online (Sandbox Code Playgroud)

  • 来自"熊猫"的作者:) (9认同)
  • 喜欢干净的解决方案! (4认同)
  • 我喜欢这个解决方案,但它是如何工作的?意思是,"幕后"发生了什么,允许`str`后跟括号从列表中选择一个特定的元素? (3认同)
  • @KevinMarkham:它是这样工作的:`str`不仅适用于字符串,而且在某种程度上也适用于列表。因此,如果您有一个字符串系列`foo`,那么`foo.str [0]`将采用每个字符串的第一个字符,而`foo.str [-1]`将采用最后一个字符。但是由于`str`也可以(部分)在列表上使用,因此`temp2.​​str [-1]`会占用Series中每个列表的最后一个元素。毕竟,字符串是字符序列,类似于列表。 (3认同)
  • 我对此感到有些困惑,单线是d1.ticker.str.split().str [-1].不是你期望的...... (2认同)

DSM*_*DSM 36

您可以将该tolist方法用作中介:

In [99]: import pandas as pd

In [100]: d1 = pd.DataFrame({'ticker' : ['spx 5/25/2001 p500', 'spx 5/25/2001 p600', 'spx 5/25/2001 p700']})

In [101]: d1.ticker.str.split().tolist()
Out[101]: 
[['spx', '5/25/2001', 'p500'],
 ['spx', '5/25/2001', 'p600'],
 ['spx', '5/25/2001', 'p700']]
Run Code Online (Sandbox Code Playgroud)

您可以从中创建一个新的DataFrame:

In [102]: d2 = pd.DataFrame(d1.ticker.str.split().tolist(), 
   .....:                   columns="symbol date price".split())

In [103]: d2
Out[103]: 
  symbol       date price
0    spx  5/25/2001  p500
1    spx  5/25/2001  p600
2    spx  5/25/2001  p700
Run Code Online (Sandbox Code Playgroud)

为了更好的衡量,您可以确定价格:

In [104]: d2["price"] = d2["price"].str.replace("p","").astype(float)

In [105]: d2
Out[105]: 
  symbol       date  price
0    spx  5/25/2001    500
1    spx  5/25/2001    600
2    spx  5/25/2001    700
Run Code Online (Sandbox Code Playgroud)

PS:但如果你真的只想要最后一栏,apply那就足够了:

In [113]: temp2.apply(lambda x: x[2])
Out[113]: 
0    p500
1    p600
2    p700
Name: ticker
Run Code Online (Sandbox Code Playgroud)

  • @JohnZwinck:哇,关于性能的五年前答案仅与性能有关,仅在[两个月前]才引入(https://github.com/pandas-dev/pandas/issues/1656) ?那是..严谨的,我给你! (3认同)

Jam*_*and 17

https://pandas.pydata.org/pandas-docs/stable/text.html

s2 = pd.Series(['a_b_c', 'c_d_e', np.nan, 'f_g_h'])
s2.str.split('_').str.get(1)
Run Code Online (Sandbox Code Playgroud)

要么

s2.str.split('_').str[1]
Run Code Online (Sandbox Code Playgroud)


All*_*LRH 6

使用 Pandas 0.20.3:

In [10]: import pandas as pd
    ...: temp = pd.DataFrame({'ticker' : ['spx 5/25/2001 p500', 'spx 5/25/2001 p600', 'spx 5/25/2001 p700']})
    ...:

In [11]: temp2 = temp.ticker.str.split(' ', expand=True)  # the expand=True return a DataFrame

In [12]: temp2
Out[12]:
     0          1     2
0  spx  5/25/2001  p500
1  spx  5/25/2001  p600
2  spx  5/25/2001  p700

In [13]: temp3 = temp.join(temp2[2])

In [14]: temp3
Out[14]:
               ticker     2
0  spx 5/25/2001 p500  p500
1  spx 5/25/2001 p600  p600
2  spx 5/25/2001 p700  p700
Run Code Online (Sandbox Code Playgroud)


sfo*_*ney 5

如果你正在寻找一句台词(就像我来这里的目的),这应该会很好:

temp2 = temp.ticker.str.split(' ', expand = True)[-1]
Run Code Online (Sandbox Code Playgroud)

您还可以简单地修改此答案以将此列分配回原始 DataFrame,如下所示:

temp['last_split'] = temp.ticker.str.split(' ', expand = True)[-1]
Run Code Online (Sandbox Code Playgroud)

我想这是这里的一个流行用例。