ホームページ  >  記事  >  バックエンド開発  >  1%の人が知っているクールなパンダの操作を教えます

1%の人が知っているクールなパンダの操作を教えます

coldplay.xixi
coldplay.xixi転載
2020-10-09 16:55:112505ブラウズ

python チュートリアル コラムでは今日の pandas の操作を紹介します。 1%の人が知っているクールなパンダの操作を教えます

pandas には accessor という非常に強力なメソッドがあり、追加のメソッドを取得できるプロパティ インターフェイスとして理解できます。実際、これはまだ非常に一般的なものなので、コードと例を通して理解しましょう。

>>> pd.Series._accessors
{'cat', 'str', 'dt'}复制代码

Series データ構造の _accessors メソッドを使用すると、3 つのオブジェクト: cat、str、dt を取得します。

  • .cat: はカテゴリデータ (カテゴリデータ) に使用されます。
  • .str: は文字データ (文字列オブジェクト) に使用されますdata)
  • .dt: 時間データ (日時のようなデータ) に使用されます

これら 3 つのオブジェクトがどのように使用されるかを順番に見てみましょう。

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 オブジェクトの 2 つのメソッドの説明:

  • Series.str.upper: Series のすべての文字列を大文字に変更します;
  • Series.str.count: Series のすべての文字を変更します文字列の数;

実際、この使用法が Python での文字列の操作と非常に似ていることを見つけるのは難しくありません。はい、パンダでもこのような単純な操作を実行できますが、違いは文字列データの列全体を操作することです。上記のデータセットに基づいて、別の操作を見てみましょう:

>>> 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 オブジェクトの 2 つのメソッドの説明:

  • Series.str.replace: Series 内の指定された文字列を置換します;
  • Series.str.extract: 正規表現を使用して文字列内のデータ情報を抽出します;

Thisこれは明らかに連鎖的な使用法であるため、使用法は少し複雑です。空の replace を通じて「 . 」を「」に置き換えます。その後、3 正規表現 (それぞれ都市、州、郵便番号に対応) を使用して、extract を通じてデータを抽出し、そして変更されました元の Series データ構造から 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 オブジェクトの使用

Series データ型: datetime

データには datetime 型が必要なため、以下では pandas の date_range() を使用して生成しますGroup date datetime は、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]复制代码

上記の 3 つの dt メソッドを説明します。

  • Series.dt.day_name(): 日付から曜日を判断します;
  • Series.dt.quarter: 日付から季節を判断します;
  • Series.dt.is_year_end: 年末かどうかを判断します。日付からの年;

他のメソッドも日時の一部の変換に基づいており、変換を使用して特定のミクロ日付またはマクロ日付を表示します。

cat オブジェクトの使用

Series データ型: category

cat オブジェクトの使用について説明する前に、Category データ型について説明します。効果は非常に強力です。メモリ内の g データを頻繁に実行することはありませんが、数行のコードの実行が長時間待機する状況に常に遭遇します。カテゴリ データを使用する利点の 1 つは、 により時間とスペースの消費を節約できることです。 いくつかの例を通して学びましょう。

>>> 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。