1%의 사람들이 알고 있는 멋진 팬더 작업을 가르쳐주세요.

coldplay.xixi
풀어 주다: 2020-10-09 16:55:11
앞으로
2530명이 탐색했습니다.

python tutorial 칼럼에서는 오늘 pandas의 동작을 소개합니다. 1%의 사람들이 알고 있는 멋진 팬더 작업을 가르쳐주세요.

pandas에는 accessor라는 매우 강력한 메소드가 있는데, 이를 통해 추가 메소드를 얻을 수 있는 속성 인터페이스로 이해할 수 있습니다. 사실 이렇게 말하는 것은 아직 매우 일반적인 일이지만, 코드와 예제를 통해 이해해 보겠습니다.

>>> pd.Series._accessors
{'cat', 'str', 'dt'}复制代码
로그인 후 복사

Series 데이터 구조에 _accessors 메서드를 사용하면 cat, str, dt라는 세 가지 개체를 얻을 수 있습니다.

  • .cat: 범주형 데이터의 경우
  • .str: 문자 데이터의 경우(문자열 개체 데이터)
  • .dt: 날짜/시간과 유사한 데이터의 경우

이 세 개체가 어떻게 작동하는지 살펴보겠습니다. 차례로 사용됩니다.

str 개체 사용

Series 데이터 유형: str string

# 定义一个Series序列
>>> addr = pd.Series([
...     'Washington, D.C. 20003',
...     'Brooklyn, NY 11211-1755',
...     'Omaha, NE 68154',
...     'Pittsburgh, PA 15211'
... ]) 

>>> addr.str.upper()
0     WASHINGTON, D.C. 20003
1    BROOKLYN, NY 11211-1755
2            OMAHA, NE 68154
3       PITTSBURGH, PA 15211
dtype: object

>>> addr.str.count(r'\d') 
0    5
1    9
2    5
3    5
dtype: int64复制代码
로그인 후 복사

위 str 개체의 두 가지 메서드에 대한 설명:

  • Series.str.upper: Series의 모든 문자열을 대문자로 변경 ;
  • Series.str.count: 시리즈의 모든 문자열 수를 계산합니다.

사실 이 사용법이 Python의 문자열 작업과 매우 유사하다는 것을 찾는 것은 어렵지 않습니다. 예, Pandas에서는 이러한 간단한 작업을 수행할 수 있지만 차이점은 문자열 데이터의 전체 열을 작업한다는 것입니다. 위의 데이터 세트를 기반으로 다른 작업을 살펴보겠습니다.

>>> regex = (r&#39;(?P<city>[A-Za-z ]+), &#39;      # 一个或更多字母
...          r&#39;(?P<state>[A-Z]{2}) &#39;        # 两个大写字母
...          r&#39;(?P<zip>\d{5}(?:-\d{4})?)&#39;)  # 可选的4个延伸数字
...
>>> addr.str.replace(&#39;.&#39;, &#39;&#39;).str.extract(regex)
         city state         zip
0  Washington    DC       20003
1    Brooklyn    NY  11211-1755
2       Omaha    NE       68154
3  Pittsburgh    PA       15211复制代码
로그인 후 복사

위 str 개체의 두 가지 메서드에 대한 설명:

  • Series.str.replace: Series에서 지정된 문자열을 바꿉니다. .str.extract:
  • 정규 표현식을 통해 문자열의 데이터 정보를 추출합니다.
  • 이 사용법은 체인 사용법임이 분명하기 때문에 약간 복잡합니다.
  • replace를 통해 "."를 ""로 바꿉니다.
그런 다음

3개의 정규 표현식(각각 도시, 주, 우편번호에 해당)을 사용하여 추출을 통해 데이터를 추출하고 원래의 시리즈 데이터 구조는 다음과 같습니다. DataFrame 데이터 구조. 물론 위의 사용법 외에도 일반적으로 사용되는 속성과 메서드에는 .rstrip, .contains, Split

등이 있습니다. 다음 코드를 통해

str 속성의 전체 목록을 확인해 보겠습니다.

>>> [i for i in dir(pd.Series.str) if not i.startswith(&#39;_&#39;)]
[&#39;capitalize&#39;,
 &#39;cat&#39;,
 &#39;center&#39;,
 &#39;contains&#39;,
 &#39;count&#39;,
 &#39;decode&#39;,
 &#39;encode&#39;,
 &#39;endswith&#39;,
 &#39;extract&#39;,
 &#39;extractall&#39;,
 &#39;find&#39;,
 &#39;findall&#39;,
 &#39;get&#39;,
 &#39;get_dummies&#39;,
 &#39;index&#39;,
 &#39;isalnum&#39;,
 &#39;isalpha&#39;,
 &#39;isdecimal&#39;,
 &#39;isdigit&#39;,
 &#39;islower&#39;,
 &#39;isnumeric&#39;,
 &#39;isspace&#39;,
 &#39;istitle&#39;,
 &#39;isupper&#39;,
 &#39;join&#39;,
 &#39;len&#39;,
 &#39;ljust&#39;,
 &#39;lower&#39;,
 &#39;lstrip&#39;,
 &#39;match&#39;,
 &#39;normalize&#39;,
 &#39;pad&#39;,
 &#39;partition&#39;,
 &#39;repeat&#39;,
 &#39;replace&#39;,
 &#39;rfind&#39;,
 &#39;rindex&#39;,
 &#39;rjust&#39;,
 &#39;rpartition&#39;,
 &#39;rsplit&#39;,
 &#39;rstrip&#39;,
 &#39;slice&#39;,
 &#39;slice_replace&#39;,
 &#39;split&#39;,
 &#39;startswith&#39;,
 &#39;strip&#39;,
 &#39;swapcase&#39;,
 &#39;title&#39;,
 &#39;translate&#39;,
 &#39;upper&#39;,
 &#39;wrap&#39;,
 &#39;zfill&#39;]复制代码
로그인 후 복사
있습니다. 특정에 대한 많은 속성을 사용하는 방법에 관심이 있다면 직접 탐색하고 연습할 수 있습니다.

dt 개체 사용

시리즈 데이터 유형: datetime

데이터에는 날짜/시간 유형이 필요하므로 다음은 pandas의 date_range()를 사용하여 dt 개체 작업을 수행하는 방법을 보여주기 위해 날짜 집합을 생성합니다.

>>> daterng = pd.Series(pd.date_range(&#39;2017&#39;, periods=9, freq=&#39;Q&#39;))
>>> daterng
0   2017-03-31
1   2017-06-30
2   2017-09-30
3   2017-12-31
4   2018-03-31
5   2018-06-30
6   2018-09-30
7   2018-12-31
8   2019-03-31
dtype: datetime64[ns]

>>>  daterng.dt.day_name()
0      Friday
1      Friday
2    Saturday
3      Sunday
4    Saturday
5    Saturday
6      Sunday
7      Monday
8      Sunday
dtype: object

>>> # 查看下半年
>>> daterng[daterng.dt.quarter > 2]
2   2017-09-30
3   2017-12-31
6   2018-09-30
7   2018-12-31
dtype: datetime64[ns]

>>> daterng[daterng.dt.is_year_end]
3   2017-12-31
7   2018-12-31
dtype: datetime64[ns]复制代码
로그인 후 복사
dt에 대한 위의 세 가지 방법:

Series.dt.day_name():
    날짜로부터 몇 주인지 판단합니다.
  • Series.dt.quarter:
  • 날짜로부터 시즌을 판단합니다.
  • Series.dt.is_year_end: 날짜를 기준으로 연말인지 판단합니다.
  • 다른 방법도 날짜/시간의 일부 변환을 기반으로 하며 변환을 사용하여 특정 마이크로 또는 매크로 날짜를 봅니다.
  • cat 객체 사용

Series 데이터 유형: Category

cat 객체 사용에 대해 이야기하기 전에 매우 강력한 Category 데이터 유형에 대해 이야기해 보겠습니다. 메모리에서 g 데이터를 자주 실행하지는 않지만, 몇 줄의 코드를 실행하면 오랜 시간이 걸리는 상황이 항상 발생합니다. 범주 데이터를 사용하면 시간과 공간을 절약할 수 있다는 이점이 있습니다.

몇 가지 예를 통해 배워봅시다.

>>> colors = pd.Series([
...     &#39;periwinkle&#39;,
...     &#39;mint green&#39;,
...     &#39;burnt orange&#39;,
...     &#39;periwinkle&#39;,
...     &#39;burnt orange&#39;,
...     &#39;rose&#39;,
...     &#39;rose&#39;,
...     &#39;mint green&#39;,
...     &#39;rose&#39;,
...     &#39;navy&#39;
... ])
...
>>> import sys
>>> colors.apply(sys.getsizeof)
0    59
1    59
2    61
3    59
4    61
5    53
6    53
7    59
8    53
9    53
dtype: int64复制代码
로그인 후 복사

위에서는 sys.getsizeof를 사용하여 메모리 사용량을 표시했으며 숫자는 바이트 수를 나타냅니다.

콘텐츠 사용량을 계산하는 또 다른 방법이 있습니다:
memory_usage()

. 이 방법은 나중에 사용됩니다.
이제 위 색상의 고유 값을 정수 세트로 매핑한 다음, 차지하는 메모리를 살펴보겠습니다.

>>> mapper = {v: k for k, v in enumerate(colors.unique())}
>>> mapper
{&#39;periwinkle&#39;: 0, &#39;mint green&#39;: 1, &#39;burnt orange&#39;: 2, &#39;rose&#39;: 3, &#39;navy&#39;: 4}

>>> as_int = colors.map(mapper)
>>> as_int
0    0
1    1
2    2
3    0
4    2
5    3
6    3
7    1
8    3
9    4
dtype: int64

>>> as_int.apply(sys.getsizeof)
0    24
1    28
2    28
3    24
4    28
5    28
6    28
7    28
8    28
9    28
dtype: int64复制代码
로그인 후 복사

참고: 위의 정수 값 매핑의 경우 더 간단한
pd.factorize()

메서드를 대신 사용할 수도 있습니다.

위에서 차지하는 메모리가 객체형을 사용할 때의 절반 정도인 것을 확인했습니다. 실제로 이 상황은 Category 데이터 유형의 내부 원칙과 유사합니다.

메모리 사용량의 차이:

Categorical이 차지하는 메모리는 Categorical 범주 수와 데이터 길이에 비례합니다. 반대로 개체가 차지하는 메모리는 데이터 길이에 상수를 곱한 값입니다.

다음은 객체 메모리 사용량과 카테고리 메모리 사용량을 비교한 것입니다.

>>> colors.memory_usage(index=False, deep=True)
650
>>> colors.astype(&#39;category&#39;).memory_usage(index=False, deep=True)
495复制代码
로그인 후 복사

上面结果是使用object和Category两种情况下内存的占用情况。我们发现效果并没有我们想象中的那么好。但是注意Category内存是成比例的,如果数据集的数据量很大,但不重复分类(unique)值很少的情况下,那么Category的内存占用可以节省达到10倍以上,比如下面数据量增大的情况:

>>> manycolors = colors.repeat(10)
>>> len(manycolors) / manycolors.nunique() 
20.0

>>> manycolors.memory_usage(index=False, deep=True)
6500
>>> manycolors.astype(&#39;category&#39;).memory_usage(index=False, deep=True)
585复制代码
로그인 후 복사

可以看到,在数据量增加10倍以后,使用Category所占内容节省了10倍以上。

除了占用内存节省外,另一个额外的好处是计算效率有了很大的提升。因为对于Category类型的Series,str字符的操作发生在.cat.categories的非重复值上,而并非原Series上的所有元素上。也就是说对于每个非重复值都只做一次操作,然后再向与非重复值同类的值映射过去。

对于Category的数据类型,可以使用accessor的cat对象,以及相应的属性和方法来操作Category数据。

>>> ccolors = colors.astype(&#39;category&#39;)
>>> ccolors.cat.categories
Index([&#39;burnt orange&#39;, &#39;mint green&#39;, &#39;navy&#39;, &#39;periwinkle&#39;, &#39;rose&#39;], dtype=&#39;object&#39;)复制代码
로그인 후 복사

实际上,对于开始的整数类型映射,我们可以先通过reorder_categories进行重新排序,然后再使用cat.codes来实现对整数的映射,来达到同样的效果。

>>> ccolors.cat.reorder_categories(mapper).cat.codes
0    0
1    1
2    2
3    0
4    2
5    3
6    3
7    1
8    3
9    4
dtype: int8复制代码
로그인 후 복사

dtype类型是Numpy的int8(-127~128)。可以看出以上只需要一个单字节就可以在内存中包含所有的值。我们开始的做法默认使用了int64类型,然而通过pandas的使用可以很智能的将Category数据类型变为最小的类型。

让我们来看一下cat还有什么其它的属性和方法可以使用。下面cat的这些属性基本都是关于查看和操作Category数据类型的。

>>> [i for i in dir(ccolors.cat) if not i.startswith(&#39;_&#39;)]
[&#39;add_categories&#39;,
 &#39;as_ordered&#39;,
 &#39;as_unordered&#39;,
 &#39;categories&#39;,
 &#39;codes&#39;,
 &#39;ordered&#39;,
 &#39;remove_categories&#39;,
 &#39;remove_unused_categories&#39;,
 &#39;rename_categories&#39;,
 &#39;reorder_categories&#39;,
 &#39;set_categories&#39;]复制代码
로그인 후 복사

但是Category数据的使用不是很灵活。例如,插入一个之前没有的值,首先需要将这个值添加到.categories的容器中,然后再添加值。

>>> ccolors.iloc[5] = &#39;a new color&#39;
# ...
ValueError: Cannot setitem on a Categorical with a new category,
set the categories first

>>> ccolors = ccolors.cat.add_categories([&#39;a new color&#39;])
>>> ccolors.iloc[5] = &#39;a new color&#39;  
复制代码
로그인 후 복사

如果你想设置值或重塑数据,而非进行新的运算操作,那么Category类型不是那么有用。

相关免费学习推荐:python教程(视频)

위 내용은 1%의 사람들이 알고 있는 멋진 팬더 작업을 가르쳐주세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.im
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿