python tutorial 칼럼에서는 오늘 pandas의 동작을 소개합니다.
pandas에는 accessor라는 매우 강력한 메소드가 있는데, 이를 통해 추가 메소드를 얻을 수 있는 속성 인터페이스로 이해할 수 있습니다. 사실 이렇게 말하는 것은 아직 매우 일반적인 일이지만, 코드와 예제를 통해 이해해 보겠습니다.
>>> pd.Series._accessors {'cat', 'str', 'dt'}复制代码
Series 데이터 구조에 _accessors 메서드를 사용하면 cat, str, dt라는 세 가지 개체를 얻을 수 있습니다.
이 세 개체가 어떻게 작동하는지 살펴보겠습니다. 차례로 사용됩니다.
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 개체의 두 가지 메서드에 대한 설명:
사실 이 사용법이 Python의 문자열 작업과 매우 유사하다는 것을 찾는 것은 어렵지 않습니다. 예, Pandas에서는 이러한 간단한 작업을 수행할 수 있지만 차이점은 문자열 데이터의 전체 열을 작업한다는 것입니다. 위의 데이터 세트를 기반으로 다른 작업을 살펴보겠습니다.
>>> regex = (r'(?P<city>[A-Za-z ]+), ' # 一个或更多字母 ... r'(?P<state>[A-Z]{2}) ' # 两个大写字母 ... r'(?P<zip>\d{5}(?:-\d{4})?)') # 可选的4个延伸数字 ... >>> 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复制代码
위 str 개체의 두 가지 메서드에 대한 설명:
3개의 정규 표현식(각각 도시, 주, 우편번호에 해당)을 사용하여 추출을 통해 데이터를 추출하고 원래의 시리즈 데이터 구조는 다음과 같습니다. DataFrame 데이터 구조. 물론 위의 사용법 외에도 일반적으로 사용되는 속성과 메서드에는 .rstrip, .contains, Split
등이 있습니다. 다음 코드를 통해str 속성의 전체 목록을 확인해 보겠습니다.
>>> [i for i in dir(pd.Series.str) if not i.startswith('_')] ['capitalize', 'cat', 'center', 'contains', 'count', 'decode', 'encode', 'endswith', 'extract', 'extractall', 'find', 'findall', 'get', 'get_dummies', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'islower', 'isnumeric', 'isspace', 'istitle', 'isupper', 'join', 'len', 'ljust', 'lower', 'lstrip', 'match', 'normalize', 'pad', 'partition', 'repeat', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'slice', 'slice_replace', 'split', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'wrap', 'zfill']复制代码
dt에 대한 위의 세 가지 방법: Series.dt.day_name():데이터에는 날짜/시간 유형이 필요하므로 다음은 pandas의 date_range()를 사용하여 dt 개체 작업을 수행하는 방법을 보여주기 위해 날짜 집합을 생성합니다.
>>> daterng = pd.Series(pd.date_range('2017', periods=9, freq='Q')) >>> 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]复制代码로그인 후 복사
cat 객체 사용에 대해 이야기하기 전에 매우 강력한 Category 데이터 유형에 대해 이야기해 보겠습니다. 메모리에서 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复制代码로그인 후 복사
위에서는 sys.getsizeof를 사용하여 메모리 사용량을 표시했으며 숫자는 바이트 수를 나타냅니다.
콘텐츠 사용량을 계산하는 또 다른 방법이 있습니다:memory_usage()pd.factorize(). 이 방법은 나중에 사용됩니다.
참고: 위의 정수 값 매핑의 경우 더 간단한
이제 위 색상의 고유 값을 정수 세트로 매핑한 다음, 차지하는 메모리를 살펴보겠습니다.>>> mapper = {v: k for k, v in enumerate(colors.unique())} >>> mapper {'periwinkle': 0, 'mint green': 1, 'burnt orange': 2, 'rose': 3, 'navy': 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复制代码로그인 후 복사
메서드를 대신 사용할 수도 있습니다.
메모리 사용량의 차이:위에서 차지하는 메모리가 객체형을 사용할 때의 절반 정도인 것을 확인했습니다. 실제로 이 상황은 Category 데이터 유형의 내부 원칙과 유사합니다.
Categorical이 차지하는 메모리는 Categorical 범주 수와 데이터 길이에 비례합니다. 반대로 개체가 차지하는 메모리는 데이터 길이에 상수를 곱한 값입니다.
다음은 객체 메모리 사용량과 카테고리 메모리 사용량을 비교한 것입니다.
>>> colors.memory_usage(index=False, deep=True) 650 >>> colors.astype('category').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('category').memory_usage(index=False, deep=True) 585复制代码로그인 후 복사可以看到,在数据量增加10倍以后,使用Category所占内容节省了10倍以上。
除了占用内存节省外,另一个额外的好处是计算效率有了很大的提升。因为对于Category类型的Series,str字符的操作发生在.cat.categories的非重复值上,而并非原Series上的所有元素上。也就是说对于每个非重复值都只做一次操作,然后再向与非重复值同类的值映射过去。
对于Category的数据类型,可以使用accessor的cat对象,以及相应的属性和方法来操作Category数据。
>>> ccolors = colors.astype('category') >>> ccolors.cat.categories Index(['burnt orange', 'mint green', 'navy', 'periwinkle', 'rose'], dtype='object')复制代码로그인 후 복사实际上,对于开始的整数类型映射,我们可以先通过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('_')] ['add_categories', 'as_ordered', 'as_unordered', 'categories', 'codes', 'ordered', 'remove_categories', 'remove_unused_categories', 'rename_categories', 'reorder_categories', 'set_categories']复制代码로그인 후 복사但是Category数据的使用不是很灵活。例如,插入一个之前没有的值,首先需要将这个值添加到.categories的容器中,然后再添加值。
>>> ccolors.iloc[5] = 'a new color' # ... ValueError: Cannot setitem on a Categorical with a new category, set the categories first >>> ccolors = ccolors.cat.add_categories(['a new color']) >>> ccolors.iloc[5] = 'a new color' 复制代码로그인 후 복사如果你想设置值或重塑数据,而非进行新的运算操作,那么Category类型不是那么有用。
相关免费学习推荐:python教程(视频)
위 내용은 1%의 사람들이 알고 있는 멋진 팬더 작업을 가르쳐주세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!