【问题标题】:How to slice each individual element of a python list or array如何切片 python 列表或数组的每个单独元素
【发布时间】:2020-01-29 00:45:06
【问题描述】:

我有一个来自 pandas 系列的 python 列表,如下所示:

dsa = pd.Series(crew_data['Work Type'])
disc = [dsa]
print(disc)

输出如下:

[0      Disc - Standard Removal & Herbicide 
 1      Disc - Standard Removal & Herbicide  
 2                            Standard Trim  
 3                       Disc - Hazard Tree  
 4                       Disc - Hazard Tree  
                  ...                   
 134                     Disc - Hazard Tree  
 135                     Disc - Hazard Tree  
 136                     Disc - Hazard Tree  
 137                     Disc - Hazard Tree  
 138                     Disc - Hazard Tree  
 Name: Work Type, Length: 139, dtype: object]

现在下一步是对每个元素的前 4 个字符进行切片,这样返回的值就是 Disc

在单个字符串上执行此操作似乎很简单,但是由于某种原因尝试使用列表执行此操作似乎几乎是不可能的。这可以在 Excel 中使用公式 =LEFT(A1,4) 简单地完成,那么它肯定可以在 python 中简单地完成吗?

如果有人有一个很棒的解决方案。

【问题讨论】:

  • 这个列表是一个大字符串,还是列表中有多个对象?你能提供一个更好的例子吗?
  • 不,这些是单独的对象。它们代表系统数据库中每个单独任务的类别代码
  • 您在crew_data['column'] 上致电pd.Series() 有什么原因吗?通常,如果crew_dataDataFrame,那么获取单个列已经会给您一个Series
  • 根据您的问题中不清楚的一些细节,您的问题可能已经在这里得到回答stackoverflow.com/questions/36505847/…
  • 感谢您的链接。这措辞完美。我在这个主题上搜索的所有内容都提供了一个带有 for 循环的函数或一些更复杂但不起作用的函数......

标签: python pandas


【解决方案1】:

带有示例数据框

In [138]: df                                                                                     
Out[138]: 
  col1  col2 col3 newcol
0    a     1    x    Wow
1    b     2    y    Dud
2    c     1    z    Wow
In [139]: df['newcol']                                                                           
Out[139]: 
0    Wow
1    Dud
2    Wow
Name: newcol, dtype: object
In [140]: type(_)                                                                                
Out[140]: pandas.core.series.Series

选择一列会给我一个系列;不需要另一个系列包装器

In [141]: pd.Series(df['newcol'])                                                                
Out[141]: 
0    Wow
1    Dud
2    Wow
Name: newcol, dtype: object

我们可以把它放在一个列表中,但这没有任何好处:

In [142]: [pd.Series(df['newcol'])]                                                              
Out[142]: 
[0    Wow
 1    Dud
 2    Wow
 Name: newcol, dtype: object]
In [143]: len(_)                                                                                 
Out[143]: 1

我们可以将值提取为一个 numpy 数组:

In [144]: pd.Series(df['newcol']).values                                                         
Out[144]: array(['Wow', 'Dud', 'Wow'], dtype=object)

我们可以对数组或序列的每个元素应用字符串切片 - 使用列表推导:

In [145]: [astr[:2] for astr in _144]                                                            
Out[145]: ['Wo', 'Du', 'Wo']
In [146]: [astr[:2] for astr in _141]                                                            
Out[146]: ['Wo', 'Du', 'Wo']

列表推导不一定是最“高级”的方式,但它是一个好的开始。实际上它已经接近最好了,因为切片字符串必须使用字符串方法;没有其他人实现字符串切片。

pandas 有一个 str 方法用于将字符串方法应用于系列:

In [147]: ds = df['newcol']  
In [151]: ds.str.slice(0,2)        # or ds.str[:2]                                                               
Out[151]: 
0    Wo
1    Du
2    Wo
Name: newcol, dtype: object

这比列表推导式更简洁、更漂亮,但实际上更慢。

【讨论】:

  • 非常好+1。是最后一个代码块,ds.str.slice(0,2)假设是df.str.slice(0,2)
  • 我错过了复制行,将Out[141] 系列分配给ds。 @merit_2
【解决方案2】:

我可能错过了问题的要点,但这是一个正则表达式实现。

import re

# Sample data
disc = ['                       Disc - Standard Removal & Herbicide ',
 '      Disc - Standard Removal & Herbicide  ',
'                           Standard Trim  ',
'                       Disc - Hazard Tree',
'                      Disc - Hazard Tree ',]

# Regular Expression pattern
# We have Disc in parenthesis because that's what we want to capture.
# Using re.search(<pattern>, <string>).group(1) returns the first matching group. Using just
# re.search(<pattern>, <string>).group() would return the entire row.
disc_pattern = r"\s+?(Disc)\s+?"

# List comprehension that skips rows without 'Disc'
[re.search(disc_pattern, i).group(1) for i in disc if re.match(disc_pattern, i)]

输出:

['Disc', 'Disc', 'Disc', 'Disc']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-10
    • 2021-10-17
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 2015-04-02
    • 2017-02-26
    相关资源
    最近更新 更多