成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Pandas之旅(四) : 可能是社區(qū)內(nèi)最實(shí)用的Pandas技巧

iflove / 2026人閱讀

摘要:不為人知的七大實(shí)用技巧大家好,我今天勤快地回來了,這一期主要是和大家分享一些的實(shí)用技巧,會(huì)在日常生活中大大提升效率,希望可以幫助到大家還是老樣子,先給大家奉上這一期的章節(jié)目錄自定義選項(xiàng),設(shè)置實(shí)用中模塊構(gòu)建測試數(shù)據(jù)巧用訪問器合并其他列拼接使用

Pandas不為人知的七大實(shí)用技巧

大家好,我今天勤快地回來了,這一期主要是和大家分享一些pandas的實(shí)用技巧,會(huì)在日常生活中大大提升效率,希望可以幫助到大家,還是老樣子,先給大家奉上這一期的章節(jié)目錄:

自定義pandas選項(xiàng),設(shè)置

實(shí)用pandas中testing模塊構(gòu)建測試數(shù)據(jù)

巧用accessor訪問器

合并其他列拼接DatetimeIndex

使用分類數(shù)據(jù)(Categorical Data)節(jié)省時(shí)間和空間

利用Mapping巧妙實(shí)現(xiàn)映射

壓縮pandas對象

源碼及GitHub地址

好啦,話不多說,讓我們一個(gè)個(gè)看吧

1. 自定義pandas選項(xiàng),設(shè)置

首先,大家可能不知道,pandas里面有一個(gè)方法pd.set_option(),利用它我們可以改變一些pandas中默認(rèn)的核心設(shè)置,
從而適應(yīng)我們自身的需要,開始前還是老樣子,讓我們先導(dǎo)入numpy和pandas包

import numpy as np
import pandas as pd
f"Using {pd.__name__}, Version {pd.__version__}"
"Using pandas, Version 0.23.0"


現(xiàn)在讓我們編寫一個(gè)start方法來實(shí)現(xiàn)自定義pandas設(shè)置

def start():
    options = {
        "display": {
            "max_columns": None,
            "max_colwidth": 25,
            "expand_frame_repr": False,  # Don"t wrap to multiple pages
            "max_rows": 14,
            "max_seq_items": 50,         # Max length of printed sequence
            "precision": 4,
            "show_dimensions": False
        },
        "mode": {
            "chained_assignment": None   # Controls SettingWithCopyWarning
        }
    }

    for category, option in options.items():
        for op, value in option.items():
            pd.set_option(f"{category}.{op}", value)  # Python 3.6+

if __name__ == "__main__":
    start()
    del start  # Clean up namespace in the interpreter

大家可以發(fā)現(xiàn),我們在方法的最后調(diào)用了pandas的set_option方法,直接利用我們自定義的參數(shù)替代了原有的pandas參數(shù),現(xiàn)在讓我們測試一下:

pd.get_option("display.max_rows")
Out:14

可以發(fā)現(xiàn)max_rows 已經(jīng)被替換成了我們設(shè)置的14,現(xiàn)在用一個(gè)真實(shí)的例子,我們利用一組公開的鮑魚各項(xiàng)指標(biāo)的數(shù)據(jù)來實(shí)驗(yàn),數(shù)據(jù)源來自機(jī)器學(xué)習(xí)平臺(tái)的公開數(shù)據(jù)

url = ("https://archive.ics.uci.edu/ml/"
       "machine-learning-databases/abalone/abalone.data")
cols = ["sex", "length", "diam", "height", "weight", "rings"]
abalone = pd.read_csv(url, usecols=[0, 1, 2, 3, 4, 8], names=cols)
abalone
sex length diam height weight rings
0 M 0.455 0.365 0.095 0.5140 15
1 M 0.350 0.265 0.090 0.2255 7
2 F 0.530 0.420 0.135 0.6770 9
3 M 0.440 0.365 0.125 0.5160 10
4 I 0.330 0.255 0.080 0.2050 7
5 I 0.425 0.300 0.095 0.3515 8
6 F 0.530 0.415 0.150 0.7775 20
... ... ... ... ... ... ...
4170 M 0.550 0.430 0.130 0.8395 10
4171 M 0.560 0.430 0.155 0.8675 8
4172 F 0.565 0.450 0.165 0.8870 11
4173 M 0.590 0.440 0.135 0.9660 10
4174 M 0.600 0.475 0.205 1.1760 9
4175 F 0.625 0.485 0.150 1.0945 10
4176 M 0.710 0.555 0.195 1.9485 12

我們可以看到,數(shù)據(jù)截?cái)酁?4行,保留了小數(shù)點(diǎn)后4位小數(shù)作為精度,和我們剛剛設(shè)置的precision=4是一樣的

2. 實(shí)用pandas中testing模塊構(gòu)建測試數(shù)據(jù)

通過pandas.util.testing提供的方法,我們可以很容易的通過幾行代碼就構(gòu)建出一個(gè)簡單的測試數(shù)據(jù)類型,比如我們現(xiàn)在構(gòu)建一個(gè)DataTime類型的數(shù)據(jù),
時(shí)間間隔為月:

import pandas.util.testing as tm
tm.N, tm.K = 15, 3         # 規(guī)定行和列

import numpy as np
np.random.seed(444)

tm.makeTimeDataFrame(freq="M").head() # 設(shè)置時(shí)間間隔為月
# tm.makeTimeDataFrame(freq="D").head()  設(shè)置時(shí)間間隔為天
A B C
2000-01-31 0.3574 -0.8804 0.2669
2000-02-29 0.3775 0.1526 -0.4803
2000-03-31 1.3823 0.2503 0.3008
2000-04-30 1.1755 0.0785 -0.1791
2000-05-31 -0.9393 -0.9039 1.1837

瞎生成一組亂七八糟的數(shù)據(jù):

tm.makeDataFrame().head()
A B C
nTLGGTiRHF -0.6228 0.6459 0.1251
WPBRn9jtsR -0.3187 -0.8091 1.1501
7B3wWfvuDA -1.9872 -1.0795 0.2987
yJ0BTjehH1 0.8802 0.7403 -1.2154
0luaYUYvy1 -0.9320 1.2912 -0.2907

關(guān)于可以隨機(jī)生成的數(shù)據(jù)類型, 一共大概有30多種,大家如果感興趣可以多試試:

[i for i in dir(tm) if i.startswith("make")]
["makeBoolIndex",
 "makeCategoricalIndex",
 "makeCustomDataframe",
 "makeCustomIndex",
 "makeDataFrame",
 "makeDateIndex",
 "makeFloatIndex",
 "makeFloatSeries",
 "makeIntIndex",
 "makeIntervalIndex",
 "makeMissingCustomDataframe",
 "makeMissingDataframe",
 "makeMixedDataFrame",
 "makeMultiIndex",
 "makeObjectSeries",
 "makePanel",
 "makePeriodFrame",
 "makePeriodIndex",
 "makePeriodPanel",
 "makePeriodSeries",
 "makeRangeIndex",
 "makeStringIndex",
 "makeStringSeries",
 "makeTimeDataFrame",
 "makeTimeSeries",
 "makeTimedeltaIndex",
 "makeUIntIndex",
 "makeUnicodeIndex"]


這樣我們?nèi)绻袦y試的需求,會(huì)很容易地構(gòu)建相對應(yīng)的假數(shù)據(jù)來測試。

3. 巧用accessor訪問器

accessor(訪問器) 具體就是類似getter和setter,當(dāng)然,Python里面不提倡存在setter和getter方法,但是這樣可以便于大家理解,pandas Series類型有3類accessor:

pd.Series._accessors

Out:{"cat", "dt", "str"}

.cat用于分類數(shù)據(jù),

.str用于字符串(對象)數(shù)據(jù),

.dt用于類似日期時(shí)間的數(shù)據(jù)。

讓我們從.str開始看:假設(shè)現(xiàn)在我們有一些原始的城市/州/ 郵編數(shù)據(jù)作為Dataframe的一個(gè)字段:

addr = pd.Series([
    "Washington, D.C. 20003",
    "Brooklyn, NY 11211-1755",
    "Omaha, NE 68154",
    "Pittsburgh, PA 15211"
])
addr.str.upper()  # 因?yàn)樽址椒ㄊ鞘噶炕?,這意味著它們在沒有顯式for循環(huán)的情況下對整個(gè)數(shù)組進(jìn)行操作
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


如果我們想把每一行分成城市,州,郵編分開,可以用正則;

regex = (r"(?P[A-Za-z ]+), "      # One or more letters
         r"(?P[A-Z]{2}) "      # 2 capital letters
         r"(?Pd{5}(?:-d{4})?)")  # Optional 4-digit extension

addr.str.replace(".", "").str.extract(regex)
city state zip
0 Washington DC 20003
1 Brooklyn NY 11211-1755
2 Omaha NE 68154
3 Pittsburgh PA 15211

第二個(gè)訪問器.dt用于類似日期時(shí)間的數(shù)據(jù)。它其實(shí)屬于Pandas的DatetimeIndex,如果在Series上調(diào)用,它首先轉(zhuǎn)換為DatetimeIndex

daterng = pd.Series(pd.date_range("2018", periods=9, freq="Q"))  # 時(shí)間間隔為季度
daterng
0   2018-03-31
1   2018-06-30
2   2018-09-30
3   2018-12-31
4   2019-03-31
5   2019-06-30
6   2019-09-30
7   2019-12-31
8   2020-03-31
dtype: datetime64[ns]



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



daterng[daterng.dt.quarter > 2]  # 查看2019年第3季度和第4季度
2   2018-09-30
3   2018-12-31
6   2019-09-30
7   2019-12-31
dtype: datetime64[ns]



daterng[daterng.dt.is_year_end]  #查看年末的一天
3   2018-12-31
7   2019-12-31
dtype: datetime64[ns]


最后有關(guān).cat訪問器我們會(huì)在第5個(gè)技巧中提到

4. 合并其他列拼接DatetimeIndex

現(xiàn)在先讓我們構(gòu)建一個(gè)包含時(shí)間類型數(shù)據(jù)的Dataframe:

from itertools import product
datecols = ["year", "month", "day"]

df = pd.DataFrame(list(product([2017, 2016], [1, 2], [1, 2, 3])),
                  columns=datecols)
df["data"] = np.random.randn(len(df))
df
year month day data
0 2017 1 1 -0.0767
1 2017 1 2 -1.2798
2 2017 1 3 0.4032
3 2017 2 1 1.2377
4 2017 2 2 -0.2060
5 2017 2 3 0.6187
6 2016 1 1 2.3786
7 2016 1 2 -0.4730
8 2016 1 3 -2.1505
9 2016 2 1 -0.6340
10 2016 2 2 0.7964
11 2016 2 3 0.0005

我們可以發(fā)現(xiàn)year,month,day是分開的三列,我們?nèi)绻胍阉鼈兒喜橥暾臅r(shí)間并作為df的索引,可以這么做:

df.index = pd.to_datetime(df[datecols])
df.head()
year month day data
2017-01-01 2017 1 1 -0.0767
2017-01-02 2017 1 2 -1.2798
2017-01-03 2017 1 3 0.4032
2017-02-01 2017 2 1 1.2377
2017-02-02 2017 2 2 -0.2060

我們可以扔掉沒用的列并把這個(gè)df壓縮為Series:

df = df.drop(datecols, axis=1).squeeze()
df.head()
2017-01-01   -0.0767
2017-01-02   -1.2798
2017-01-03    0.4032
2017-02-01    1.2377
2017-02-02   -0.2060
Name: data, dtype: float64



type(df)
pandas.core.series.Series



df.index.dtype_str
"datetime64[ns]"


5. 使用分類數(shù)據(jù)(Categorical Data)節(jié)省時(shí)間和空間

剛剛我們在第3個(gè)技巧的時(shí)候提到了訪問器,現(xiàn)在讓我們來看最后一個(gè).cat

pandas中Categorical這個(gè)數(shù)據(jù)類型非常強(qiáng)大,通過類型轉(zhuǎn)換可以讓我們節(jié)省變量在內(nèi)存占用的空間,提高運(yùn)算速度,不過有關(guān)具體的pandas加速實(shí)戰(zhàn),我會(huì)在
下一期說,現(xiàn)在讓我們來看一個(gè)小栗子:

colors = pd.Series([
    "periwinkle",
    "mint green",
    "burnt orange",
    "periwinkle",
    "burnt orange",
    "rose",
    "rose",
    "mint green",
    "rose",
    "navy"
])

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


我們首先創(chuàng)建了一個(gè)Series,填充了各種顏色,接著查看了每個(gè)地址對應(yīng)的顏色所占內(nèi)存的大小

注意這里我們使用sys.getsizeof()來獲取占內(nèi)存大小,但是實(shí)際上空格也是占內(nèi)存的,sys.getsizeof("")返回的是49bytes

接下來我們想把每種顏色用占內(nèi)存更少的數(shù)字來表示(機(jī)器學(xué)習(xí)種非常常見),這樣可以減少占用的內(nèi)存,首先讓我們創(chuàng)建一個(gè)mapper字典,給每一種顏色指定
一個(gè)數(shù)字

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


接著我們把剛才的colors數(shù)組轉(zhuǎn)化為int類型:

# 也可以通過 pd.factorize(colors)[0] 實(shí)現(xiàn)
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


再讓我們看一下占用的內(nèi)存:

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


現(xiàn)在可以觀察到我們的內(nèi)存占用的空間幾乎是之前的一半,其實(shí),剛剛我們做的正是模擬Categorical Data的轉(zhuǎn)化原理?,F(xiàn)在讓我們直接調(diào)用一下:

colors.memory_usage(index=False, deep=True)

Out:650
colors.astype("category").memory_usage(index=False, deep=True)

Out: 495

大家可能感覺節(jié)省的空間并不是非常大對不對? 因?yàn)槟壳拔覀冞@個(gè)數(shù)據(jù)根本不是真實(shí)場景,我們僅僅把數(shù)據(jù)容量增加10倍,現(xiàn)在再讓我們看看效果:

manycolors = colors.repeat(10)
len(manycolors) / manycolors.nunique()  # Much greater than 2.0x 

Out:20.0
f"Not using category : { manycolors.memory_usage(index=False, deep=True)}"
"Not using category : 6500"



f"Using category : { manycolors.astype("category").memory_usage(index=False, deep=True)}"
"Using category : 585"


這回內(nèi)存的占用量差距明顯就出來了,現(xiàn)在讓我們用.cat來簡化一下剛剛的工作:

new_colors = colors.astype("category")
new_colors
0      periwinkle
1      mint green
2    burnt orange
3      periwinkle
4    burnt orange
5            rose
6            rose
7      mint green
8            rose
9            navy
dtype: category
Categories (5, object): [burnt orange, mint green, navy, periwinkle, rose]



new_colors.cat.categories   # 可以使用.cat.categories查看代表的顏色
Index(["burnt orange", "mint green", "navy", "periwinkle", "rose"], dtype="object")


現(xiàn)在讓我們查看把顏色代表的數(shù)字:

new_colors.cat.codes
0    3
1    1
2    0
3    3
4    0
5    4
6    4
7    1
8    4
9    2
dtype: int8


我們?nèi)绻粷M意順序也可以從新排序:

new_colors.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


有關(guān)cat其他的方法,我們還是可以通過遍歷dir來查看:

[i for i in dir(new_colors.cat) if not i.startswith("_")]
["add_categories",
 "as_ordered",
 "as_unordered",
 "categories",
 "codes",
 "ordered",
 "remove_categories",
 "remove_unused_categories",
 "rename_categories",
 "reorder_categories",
 "set_categories"]


Categorical 數(shù)據(jù)通常不太靈活,比如我們不能直接在new_colors上新增一個(gè)新的顏色,要首先通過
.add_categories來添加
ccolors.iloc[5] = "a new color"
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

 in ()
----> 1 ccolors.iloc[5] = "a new color"


NameError: name "ccolors" is not defined


new_colors = new_colors.cat.add_categories(["a new color"])
new_colors.iloc[5] = "a new color"  # 不會(huì)報(bào)錯(cuò)
new_colors.values  # 成功添加
6. 利用Mapping巧妙實(shí)現(xiàn)映射

假設(shè)現(xiàn)在我們有存貯國家的一組數(shù)據(jù),和一組用來映射國家所對應(yīng)的大洲的數(shù)據(jù):

countries = pd.Series([
    "United States",
    "Canada",
    "Mexico",
    "Belgium",
    "United Kingdom",
    "Thailand"
])

groups = {
    "North America": ("United States", "Canada", "Mexico", "Greenland"),
    "Europe": ("France", "Germany", "United Kingdom", "Belgium")
}

我們可以通過下面的方法來實(shí)現(xiàn)簡單的映射:

from typing import Any

def membership_map(s: pd.Series, groups: dict,
                   fillvalue: Any=-1) -> pd.Series:
    # Reverse & expand the dictionary key-value pairs
    groups = {x: k for k, v in groups.items() for x in v}
    return s.map(groups).fillna(fillvalue)
 membership_map(countries, groups, fillvalue="other")

很簡單對不對,現(xiàn)在讓我們看一下最關(guān)鍵的一行代碼,groups = {x: k for k, v in groups.items() for x in v},這個(gè)是我之前提到過的字典推導(dǎo)式:

test = dict(enumerate(("ab", "cd", "xyz")))
{x: k for k, v in test.items() for x in v}
7. 壓縮pandas對象
如果你的pandas版本大于0.21.0,那么都可以直接把pandas用壓縮形式寫入,常見的類型有g(shù)zip, bz2, zip,這里我們直接用剛才鮑魚的數(shù)據(jù)集:
abalone.to_json("df.json.gz", orient="records",lines=True, compression="gzip")  # 壓縮為gz類型
abalone.to_json("df.json", orient="records", lines=True)                        #壓縮為json
import os.path
os.path.getsize("df.json") / os.path.getsize("df.json.gz")  #壓縮大小差了10倍,還是gz更厲害
8. 源碼及GitHub地址

這一期為大家總結(jié)了很多pandas實(shí)用的小技巧,希望大家喜歡

我把這一期的ipynb文件和py文件放到了Github上,大家如果想要下載可以點(diǎn)擊下面的鏈接:

Github倉庫地址: https://github.com/yaozeliang/pandas_share

這一期就到這里啦,希望大家能夠繼續(xù)支持我,完結(jié),撒花

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/43390.html

相關(guān)文章

  • Pandas之旅(七) 誰說pandas

    摘要:下面讓我們開始提速假設(shè)我們現(xiàn)在的電價(jià)是定值,不根據(jù)用電時(shí)間段來改變,那么中最快的方法那就是采用,這就是一個(gè)簡單的矢量化操作示范。它基本是在中運(yùn)行最快的方式。 Pandas 加速 大家好,今天我們來看有關(guān)pandas加速的小技巧,不知道大家在剛剛接觸pandas的時(shí)候有沒有聽過如下的說法 pandas太慢了,運(yùn)行要等半天 其實(shí)我想說的是,慢不是pandas的錯(cuò),大家要知道pandas本身...

    genedna 評論0 收藏0
  • Pandas之旅(一): 讓我們把基礎(chǔ)知識一次擼完,申精干貨

    為什么你需要pandas 大家好,今天想和大家分享一下有關(guān)pandas的學(xué)習(xí)新的,我因工作需要,從去年12月開始接觸這個(gè)非常好用的包,到現(xiàn)在為止也是算是熟悉了一些,因此發(fā)現(xiàn)了它的強(qiáng)大之處,特意想要和朋友們分享,特別是如果你每天和excel打交道,總是需要編寫一些vba函數(shù)或者對行列進(jìn)行g(shù)roupby啊,merge,join啊之類的,相信我,pandas會(huì)讓你解脫的。 好啦,閑話少說,這篇文章的基礎(chǔ)...

    tuomao 評論0 收藏0
  • Pandas之旅(六): 字符串實(shí)用方法匯總

    摘要:有關(guān)字符串基本方法大家好,我又回來了之前的幾期我們已經(jīng)簡單了解了的基礎(chǔ)操作,但是只要涉及到數(shù)據(jù),最常見的就是字符串類型,所以很多時(shí)候我們其實(shí)都在和字符串打交道,所以今天,我會(huì)把我自己總結(jié)的,有關(guān)字符串的常用方法分享給大家,希望能夠幫到各位小 有關(guān)字符串基本方法 大家好,我又回來了! 之前的幾期我們已經(jīng)簡單了解了pandas的基礎(chǔ)操作,但是只要涉及到數(shù)據(jù),最常見的就是String(字符串...

    高勝山 評論0 收藏0
  • Pandas之旅(三)最實(shí)用Merge, Join,Concat方法詳解

    摘要:基于上的我們還可以實(shí)現(xiàn)幾個(gè)基于的,還是老樣子,先讓我們創(chuàng)建兩個(gè)好了,現(xiàn)在我們想要實(shí)現(xiàn)兩個(gè)的,但是條件是通過的和的這樣我們也可以得到結(jié)果。 Merge, Join, Concat 大家好,我有回來啦,這周更新的有點(diǎn)慢,主要是因?yàn)槲腋铝藗€(gè)人簡歷哈哈,如果感興趣的朋友可以去看看哈: 我的主頁 個(gè)人認(rèn)為還是很漂亮的~,不得不說,很多時(shí)候老外的設(shè)計(jì)能力還是很強(qiáng)。 好了,有點(diǎn)扯遠(yuǎn)了,這一期我想和...

    CloudwiseAPM 評論0 收藏0
  • ApacheCN 學(xué)習(xí)資源匯總 2019.3

    摘要:主頁暫時(shí)下線社區(qū)暫時(shí)下線知識庫自媒體平臺(tái)微博知乎簡書博客園合作侵權(quán),請聯(lián)系請抄送一份到特色項(xiàng)目中文文檔和教程與機(jī)器學(xué)習(xí)實(shí)用指南人工智能機(jī)器學(xué)習(xí)數(shù)據(jù)科學(xué)比賽系列項(xiàng)目實(shí)戰(zhàn)教程文檔代碼視頻數(shù)據(jù)科學(xué)比賽收集平臺(tái),,劍指,經(jīng)典算法實(shí)現(xiàn)系列課本課本描述 【主頁】 apachecn.org 【Github】@ApacheCN 暫時(shí)下線: 社區(qū) 暫時(shí)下線: cwiki 知識庫 自媒體平臺(tái) ...

    array_huang 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<