Pandas document learning
0. Introduction
What is Pandas?
Pandas is a powerful tool set for analyzing structured data; Its use is based on Numpy (providing high-performance matrix operation); It is used for data mining and data analysis, and also provides data cleaning function.
One of the sharp tools: DataFrame
DataFrame is a tabular data structure in Pandas, which contains a group of ordered columns. Each column can be of different value types (numeric, string, Boolean, etc.). DataFrame has both row index and column index, which can be regarded as a dictionary composed of Series.
One of the sharp tools: Series
It is an object similar to one-dimensional array, which is composed of a set of data (various NumPy data types) and a set of related data labels (i.e. indexes). Simple Series objects can also be generated from only one set of data.
1. Basic use
# 1. Installation package $ pip install pandas # 2. Enter the interactive interface of python $ python -i # 3. Using Pandas >>> import pandas as pd >>> df = pd.DataFrame() >>> print(df) # 4. Output results Empty DataFrame Columns: [] Index: []
2. Data structure
dimension | name | describe |
---|---|---|
1 | Series | Labeled one-dimensional isomorphic array |
2 | DataFrame | Labeled, variable size, two-dimensional heterogeneous table |
Why are there multiple data structures? Why are there multiple data structures?
Pandas data structure is like a container of low dimensional data. For example, DataFrame is the container of Series, and Series is the container of scalar. In this way, you can insert or delete objects in the container as a dictionary.
In addition, the default operation of general API functions takes into account the direction of time series and cross-sectional data sets. When multidimensional arrays store two-dimensional or three-dimensional data, the direction of the data set should be paid attention to when writing functions, which is a burden for users; If you do not consider the impact of continuity on performance in C or Fortran, in general, there is no difference between different axes in the program. In Pandas, the concept of axis is mainly to give more intuitive semantics to data, that is, to represent the direction of data set in a "more appropriate" way. This allows users to spend less time writing data conversion functions.
When dealing with table data such as DataFrame, index es (rows) or columns (columns) are more intuitive than axis 0 and axis 1. Iterating over the columns of the DataFrame in this way makes the code easier to read and understand:
3. Generate object
Generate with value list Series (opens new window) When, Pandas automatically generates integer indexes by default:
In [3]: s = pd.Series([1, 3, 5, np.nan, 6, 8]) In [4]: s Out[4]: 0 1.0 1 3.0 2 5.0 3 NaN 4 6.0 5 8.0 dtype: float64
Generated from NumPy array with date time index and label DataFrame (opens new window):
In [5]: dates = pd.date_range('20130101', periods=6) In [6]: dates Out[6]: DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'], dtype='datetime64[ns]', freq='D') In [7]: df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD')) In [8]: df Out[8]: A B C D 2013-01-01 0.469112 -0.282863 -1.509059 -1.135632 2013-01-02 1.212112 -0.173215 0.119209 -1.044236 2013-01-03 -0.861849 -2.104569 -0.494929 1.071804 2013-01-04 0.721555 -0.706771 -1.039575 0.271860 2013-01-05 -0.424972 0.567020 0.276232 -1.087401 2013-01-06 -0.673690 0.113648 -1.478427 0.524988
Generate DataFrame with Series dictionary object:
In [9]: df2 = pd.DataFrame({'A': 1., ...: 'B': pd.Timestamp('20130102'), ...: 'C': pd.Series(1, index=list(range(4)), dtype='float32'), ...: 'D': np.array([3] * 4, dtype='int32'), ...: 'E': pd.Categorical(["test", "train", "test", "train"]), ...: 'F': 'foo'}) ...: In [10]: df2 Out[10]: A B C D E F 0 1.0 2013-01-02 1.0 3 test foo 1 1.0 2013-01-02 1.0 3 train foo 2 1.0 2013-01-02 1.0 3 test foo 3 1.0 2013-01-02 1.0 3 train foo
df2 this DataFrame (opens new window) It contains many types, DataFrame.to_numpy() (opens new window) Operation will consume more resources.
In [18]: df2.to_numpy() Out[18]: array([[1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'test', 'foo'], [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'train', 'foo'], [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'test', 'foo'], [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'train', 'foo']], dtype=object)
4. Index and column names
import pandas as pd import numpy as np if __name__ == '__main__': dates = pd.date_range('20130101', periods=6) df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD')) print(df) print(df.index) # Indexes print(df.columns) # Listing
A B C D 2013-01-01 1.085858 0.050717 -0.004593 -0.676837 2013-01-02 1.038949 0.851006 -0.974027 0.752497 2013-01-03 -0.100549 0.826659 0.396123 -1.912859 2013-01-04 -0.856628 0.360576 0.068805 2.466386 2013-01-05 0.031247 0.487285 0.459623 0.451538 2013-01-06 -2.590153 0.573421 0.142820 -0.628175 DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'], dtype='datetime64[ns]', freq='D') Index(['A', 'B', 'C', 'D'], dtype='object')
5. Sorting
Transpose data:
In [20]: df.T Out[20]: 2013-01-01 2013-01-02 2013-01-03 2013-01-04 2013-01-05 2013-01-06 A 0.469112 1.212112 -0.861849 0.721555 -0.424972 -0.673690 B -0.282863 -0.173215 -2.104569 -0.706771 0.567020 0.113648 C -1.509059 0.119209 -0.494929 -1.039575 0.276232 -1.478427 D -1.135632 -1.044236 1.071804 0.271860 -1.087401 0.524988
Sort by axis:
In [21]: df.sort_index(axis=1, ascending=False) Out[21]: D C B A 2013-01-01 -1.135632 -1.509059 -0.282863 0.469112 2013-01-02 -1.044236 0.119209 -0.173215 1.212112 2013-01-03 1.071804 -0.494929 -2.104569 -0.861849 2013-01-04 0.271860 -1.039575 -0.706771 0.721555 2013-01-05 -1.087401 0.276232 0.567020 -0.424972 2013-01-06 0.524988 -1.478427 0.113648 -0.673690
Sort by value:
In [22]: df.sort_values(by='B') Out[22]: A B C D 2013-01-03 -0.861849 -2.104569 -0.494929 1.071804 2013-01-04 0.721555 -0.706771 -1.039575 0.271860 2013-01-01 0.469112 -0.282863 -1.509059 -1.135632 2013-01-02 1.212112 -0.173215 0.119209 -1.044236 2013-01-06 -0.673690 0.113648 -1.478427 0.524988 2013-01-05 -0.424972 0.567020 0.276232 -1.087401
6. Selection
Select by label
See details Select by label (opens new window).
Extract a row of data with labels:
In [26]: df.loc[dates[0]] Out[26]: A 0.469112 B -0.282863 C -1.509059 D -1.135632 Name: 2013-01-01 00:00:00, dtype: float64
Select multiple columns of data with labels:
In [27]: df.loc[:, ['A', 'B']] Out[27]: A B 2013-01-01 0.469112 -0.282863 2013-01-02 1.212112 -0.173215 2013-01-03 -0.861849 -2.104569 2013-01-04 0.721555 -0.706771 2013-01-05 -0.424972 0.567020 2013-01-06 -0.673690 0.113648
Slice with label, including row and column end points:
In [28]: df.loc['20130102':'20130104', ['A', 'B']] Out[28]: A B 2013-01-02 1.212112 -0.173215 2013-01-03 -0.861849 -2.104569 2013-01-04 0.721555 -0.706771
Dimension reduction of returned object:
In [29]: df.loc['20130102', ['A', 'B']] Out[29]: A 1.212112 B -0.173215 Name: 2013-01-02 00:00:00, dtype: float64
Extract scalar value:
In [30]: df.loc[dates[0], 'A'] Out[30]: 0.46911229990718628
Fast access scalar, equivalent to the above method:
In [31]: df.at[dates[0], 'A'] Out[31]: 0.46911229990718628
Select by location
See details Select by location (opens new window).
Select with integer position:
In [32]: df.iloc[3] Out[32]: A 0.721555 B -0.706771 C -1.039575 D 0.271860 Name: 2013-01-04 00:00:00, dtype: float64
Similar to NumPy / Python, slice with integer:
In [33]: df.iloc[3:5, 0:2] Out[33]: A B 2013-01-04 0.721555 -0.706771 2013-01-05 -0.424972 0.567020
Similar to NumPy / Python, slice by position with an integer list:
In [34]: df.iloc[[1, 2, 4], [0, 2]] Out[34]: A C 2013-01-02 1.212112 0.119209 2013-01-03 -0.861849 -0.494929 2013-01-05 -0.424972 0.276232
Explicit whole row slice:
In [35]: df.iloc[1:3, :] Out[35]: A B C D 2013-01-02 1.212112 -0.173215 0.119209 -1.044236 2013-01-03 -0.861849 -2.104569 -0.494929 1.071804
Explicit column slicing:
In [36]: df.iloc[:, 1:3] Out[36]: B C 2013-01-01 -0.282863 -1.509059 2013-01-02 -0.173215 0.119209 2013-01-03 -2.104569 -0.494929 2013-01-04 -0.706771 -1.039575 2013-01-05 0.567020 0.276232 2013-01-06 0.113648 -1.478427
Explicitly extract values:
In [37]: df.iloc[1, 1] Out[37]: -0.17321464905330858
Fast access scalar, equivalent to the above method:
In [38]: df.iat[1, 1] Out[38]: -0.17321464905330858
Boolean index
Select data with single column values:
In [39]: df[df.A > 0] Out[39]: A B C D 2013-01-01 0.469112 -0.282863 -1.509059 -1.135632 2013-01-02 1.212112 -0.173215 0.119209 -1.044236 2013-01-04 0.721555 -0.706771 -1.039575 0.271860
Select the value that meets the conditions in the DataFrame:
In [40]: df[df > 0] Out[40]: A B C D 2013-01-01 0.469112 NaN NaN NaN 2013-01-02 1.212112 NaN 0.119209 NaN 2013-01-03 NaN NaN NaN 1.071804 2013-01-04 0.721555 NaN NaN 0.271860 2013-01-05 NaN 0.567020 0.276232 NaN 2013-01-06 NaN 0.113648 NaN 0.524988
use isin() (opens new window) Filter:
In [41]: df2 = df.copy() In [42]: df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three'] In [43]: df2 Out[43]: A B C D E 2013-01-01 0.469112 -0.282863 -1.509059 -1.135632 one 2013-01-02 1.212112 -0.173215 0.119209 -1.044236 one 2013-01-03 -0.861849 -2.104569 -0.494929 1.071804 two 2013-01-04 0.721555 -0.706771 -1.039575 0.271860 three 2013-01-05 -0.424972 0.567020 0.276232 -1.087401 four 2013-01-06 -0.673690 0.113648 -1.478427 0.524988 three In [44]: df2[df2['E'].isin(['two', 'four'])] Out[44]: A B C D E 2013-01-03 -0.861849 -2.104569 -0.494929 1.071804 two 2013-01-05 -0.424972 0.567020 0.276232 -1.087401 four
7. Missing value
Pandas mainly uses NP Nan indicates missing data. During calculation, null values are not included by default. See details Missing data (opens new window).
reindex can change, add and delete the index of the specified axis, and return a copy of the data, that is, the original data will not be changed.
In [55]: df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E']) In [56]: df1.loc[dates[0]:dates[1], 'E'] = 1 In [57]: df1 Out[57]: A B C D F E 2013-01-01 0.000000 0.000000 -1.509059 5 NaN 1.0 2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0 2013-01-03 -0.861849 -2.104569 -0.494929 5 2.0 NaN 2013-01-04 0.721555 -0.706771 -1.039575 5 3.0 NaN
Delete all rows with missing values:
In [58]: df1.dropna(how='any') Out[58]: A B C D F E 2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
Fill in missing values:
In [59]: df1.fillna(value=5) Out[59]: A B C D F E 2013-01-01 0.000000 0.000000 -1.509059 5 5.0 1.0 2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0 2013-01-03 -0.861849 -2.104569 -0.494929 5 2.0 5.0 2013-01-04 0.721555 -0.706771 -1.039575 5 3.0 5.0
Boolean mask to extract nan value:
In [60]: pd.isna(df1) Out[60]: A B C D F E 2013-01-01 False False False False True False 2013-01-02 False False False False False False 2013-01-03 False False False False False True 2013-01-04 False False False False False True
8. Operation
a. Histogram
See details Histogram and discretization (opens new window).
In [68]: s = pd.Series(np.random.randint(0, 7, size=10)) In [69]: s Out[69]: 0 4 1 2 2 1 3 2 4 6 5 4 6 4 7 6 8 4 9 4 dtype: int64 In [70]: s.value_counts() Out[70]: 4 5 6 2 2 2 1 1 dtype: int64
b. String method
The str property of Series contains a set of string processing functions, as shown in the following code. Note that STR's pattern matching is used by default Regular expression (opens new window) . See details Vector string method (opens new window).
The str property of Series contains a set of string processing functions, as shown in the following code. Note that STR's pattern matching is used by default Regular expression (opens new window) . See details Vector string method (opens new window).
In [71]: s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat']) In [72]: s.str.lower() Out[72]: 0 a 1 b 2 c 3 aaba 4 baca 5 NaN 6 caba 7 dog 8 cat dtype: object
c. join
SQL style merge. See details Database style connection (opens new window).
In [77]: left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]}) In [78]: right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]}) In [79]: left Out[79]: key lval 0 foo 1 1 foo 2 In [80]: right Out[80]: key rval 0 foo 4 1 foo 5 In [81]: pd.merge(left, right, on='key') Out[81]: key lval rval 0 foo 1 4 1 foo 1 5 2 foo 2 4 3 foo 2 5
d. Append
Append rows to DataFrame. See details Append (opens new window) file.
In [87]: df = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D']) In [88]: df Out[88]: A B C D 0 1.346061 1.511763 1.627081 -0.990582 1 -0.441652 1.211526 0.268520 0.024580 2 -1.577585 0.396823 -0.105381 -0.532532 3 1.453749 1.208843 -0.080952 -0.264610 4 -0.727965 -0.589346 0.339969 -0.693205 5 -0.339355 0.593616 0.884345 1.591431 6 0.141809 0.220390 0.435589 0.192451 7 -0.096701 0.803351 1.715071 -0.708758 In [89]: s = df.iloc[3] In [90]: df.append(s, ignore_index=True) Out[90]: A B C D 0 1.346061 1.511763 1.627081 -0.990582 1 -0.441652 1.211526 0.268520 0.024580 2 -1.577585 0.396823 -0.105381 -0.532532 3 1.453749 1.208843 -0.080952 -0.264610 4 -0.727965 -0.589346 0.339969 -0.693205 5 -0.339355 0.593616 0.884345 1.591431 6 0.141809 0.220390 0.435589 0.192451 7 -0.096701 0.803351 1.715071 -0.708758 8 1.453749 1.208843 -0.080952 -0.264610
9. Grouping
In [91]: df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', ....: 'foo', 'bar', 'foo', 'foo'], ....: 'B': ['one', 'one', 'two', 'three', ....: 'two', 'two', 'one', 'three'], ....: 'C': np.random.randn(8), ....: 'D': np.random.randn(8)}) ....: In [92]: df Out[92]: A B C D 0 foo one -1.202872 -0.055224 1 bar one -1.814470 2.395985 2 foo two 1.018601 1.552825 3 bar three -0.595447 0.166599 4 foo two 1.395433 0.047609 5 bar two -0.392670 -0.136473 6 foo one 0.007207 -0.561757 7 foo three 1.928123 -1.623033
Group first, then sum() (opens new window) The function calculates the summary data for each group:
In [93]: df.groupby('A').sum() Out[93]: C D A bar -2.802588 2.42611 foo 3.146492 -0.63958
After grouping multiple columns, a multi-layer index is generated. You can also apply the sum function:
In [94]: df.groupby(['A', 'B']).sum() Out[94]: C D A B bar one -1.814470 2.395985 three -0.595447 0.166599 two -0.392670 -0.136473 foo one -1.195665 -0.616981 three 1.928123 -1.623033 two 2.414034 1.600434
Reference documents
http://www.pypandas.cn/