Informatics Practices: Class 12 — Chapter 2: Data Handling Using Pandas - I

2.1 Introduction to Python Libraries

Python libraries contain collections of built-in modules that allow developers to perform complex tasks without writing detailed programs from scratch. Each library contains numerous modules that can be imported and utilized.

Technical Profile: Core Python Data Science Libraries

  • NumPy (Numerical Python): Used for scientific computing, multidimensional array operations ( ndarray ), and efficient memory management.
  • Pandas (PANel DAta): A high-level data manipulation tool built on top of NumPy and Matplotlib, designed for structured data analysis and visualization.
  • Matplotlib: Used for plotting high-quality graphs, histograms, bar charts, and scatterplots with minimal code.
Key Differences: Pandas vs NumPy
  1. A NumPy array requires homogeneous data, whereas a Pandas DataFrame can store heterogeneous data types (e.g., float, int, string, datetime).
  2. Pandas provides a simpler interface for operations like file loading, plotting, selection, joining, and grouping ( GROUP BY ).
  3. Pandas DataFrames use explicit column names, making data tracking highly intuitive.
  4. Pandas is optimized for tabular data formats, while NumPy is designed for low-level numeric array-based manipulations.
2.1.1 Installing Pandas

Pandas can be installed via the command line using the Python package installer:

  
  pip install pandas

Note: Both NumPy and Pandas require Python to be pre-installed on the system.

2.1.2 Data Structures in Pandas

A data structure is a collection of data values and operations that can be applied to that data, enabling efficient storage, retrieval, and modification. Pandas primarily uses two data structures:

  • Series: A one-dimensional array-like structure.
  • DataFrame: A two-dimensional tabular structure.
2.2 Pandas Series

A Series is a one-dimensional array containing a sequence of values of any data type (int, float, list, string, etc.), which by default have numeric data labels starting from zero. The data label associated with a particular value is called its index .

2.2.1 Creation of Series

To create or use a Series, the Pandas library must first be imported:

  
  import pandas as pd

(A) Creation of Series from Scalar Values:

  
    >>> series1 = pd.Series([10, 20, 30])
    >>> print(series1)
    0    10
    1    20
    2    30
    dtype: int64
  

(B) Creation of Series with User-Defined Indices:

  
    >>> series2 = pd.Series(["Kavi", "Shyam", "Ravi"], index=[3, 5, 1])
    >>> print(series2)
    3     Kavi
    5    Shyam
    1     Ravi
    dtype: object
  

(C) Creation of Series from NumPy Arrays:

  
    >>> import numpy as np
    >>> array1 = np.array([1, 2, 3, 4])
    >>> series3 = pd.Series(array1)
    >>> print(series3)
    0    1
    1    2
    2    3
    3    4
    dtype: int32
  

Note: If index labels are passed with a NumPy array, the length of the index and the array must match, otherwise a ValueError is raised.

(D) Creation of Series from a Dictionary:

  
    >>> dict1 = {'India': 'NewDelhi', 'UK': 'London', 'Japan': 'Tokyo'}
    >>> series8 = pd.Series(dict1)
    >>> print(series8)
    India    NewDelhi
    UK         London
    Japan       Tokyo
    dtype: object
  
2.2.2 Accessing Elements of a Series

Elements of a Series can be accessed using two primary methods: Indexing and Slicing .

(A) Indexing:

  • Positional Index: Uses integer values corresponding to the position starting from 0.
  • Labelled Index: Uses user-defined labels.
  
    >>> seriesNum = pd.Series([10, 20, 30])
    >>> seriesNum[2]
    30
  

Accessing multiple elements using a list of indices:

  
    >>> seriesCapCntry[['UK', 'USA']]
    UK           London
    USA    WashingtonDC
    dtype: object
  

(B) Slicing:

Slicing extracts a subset of a Series using the syntax [start:end] .

  • Positional Slicing: Excludes the end index value (i.e., extracts up to end - 1 ).
  • Labelled Slicing: Includes the end index value.
  
    >>> seriesCapCntry[1:3]
    USA    WashingtonDC
    UK           London
    dtype: object
    >>> seriesCapCntry['USA':'France']
    USA       WashingtonDC
    UK              London
    France           Paris
    dtype: object
  

Reversing a Series using slicing:

  
  >>> seriesCapCntry[::-1]

2.2.3 Attributes of Series

The following table details the core attributes of a Pandas Series:

Attribute Name Purpose Example Syntax
name Assigns or retrieves a name for the Series series.name = 'Capitals'
index.name Assigns or retrieves a name for the index of the Series series.index.name = 'Countries'
values Returns a list of values in the Series as a NumPy ndarray series.values
size Returns the number of elements in the Series series.size
empty Returns True if the Series is empty, otherwise False series.empty
2.2.4 Methods of Series
Method Explanation Example Syntax
head(n) Returns the first n elements of the Series (default is 5) series.head(2)
count() Returns the number of non-NaN (non-null) values in the Series series.count()
tail(n) Returns the last n elements of the Series (default is 5) series.tail(2)
2.2.5 Mathematical Operations on Series

Mathematical operations on Series align data based on index labels. If an index is present in one Series but not the other, the resulting value is marked as NaN (Not a Number).

Using Operators vs Methods:

  • Operators ( + , - , * , / ): Perform operations but result in NaN for missing indices.
  • Methods ( add() , sub() , mul() , div() ): Allow the use of the fill_value parameter to replace missing values before calculation.
  
    >>> # Addition with operator
    >>> seriesA + seriesB
    a     -9.0
    b      NaN
    c    -47.0
    >>> # Addition with method and fill_value
    >>> seriesA.add(seriesB, fill_value=0)
    a     -9.0
    b      2.0
    c    -47.0
  
2.3 Pandas DataFrame

A DataFrame is a two-dimensional, tabular, labelled data structure containing rows and columns. It has both a row index and a column index, and can store heterogeneous data types.

2.3.1 Creation of DataFrame

DataFrames can be created from various inputs:

  • Empty DataFrame: pd.DataFrame()
  • NumPy ndarrays:
      
      >>> dFrame = pd.DataFrame([array1, array2], columns=['A', 'B', 'C', 'D'])
    
    
  • List of Dictionaries: Keys become column labels; missing keys are filled with NaN .
      
        >>> listDict = [{'a': 10, 'b': 20}, {'a': 5, 'b': 10, 'c': 20}]
        >>> dFrame = pd.DataFrame(listDict)
      
    
  • Dictionary of Lists: Keys become column labels, and lists become column values.
      
        >>> dictForest = {'State': ['Assam', 'Delhi'], 'GArea': [78438, 1483]}
        >>> dFrame = pd.DataFrame(dictForest)
      
    
  • Dictionary of Series:
      
      >>> dFrame = pd.DataFrame({'Series1': seriesA, 'Series2': seriesB})
    
    
2.3.2 Operations on Rows and Columns
  • Adding a Column:
        
        >>> ResultDF['Preeti'] = [89, 78, 76]
      
    
  • Adding a Row (using .loc[] ):
      
      >>> ResultDF.loc['English'] = [85, 86, 83, 80, 90, 89]
    
    
  • Deleting Rows or Columns (using .drop() ):

    Use axis=0 for rows and axis=1 for columns.

      
        >>> ResultDF = ResultDF.drop('Science', axis=0) # Drops row
        >>> ResultDF = ResultDF.drop(['Samridhi', 'Riya'], axis=1) # Drops columns
      
    
  • Renaming Labels (using .rename() ):
      
        >>> ResultDF = ResultDF.rename({'Maths': 'Sub1'}, axis='index')
        >>> ResultDF = ResultDF.rename({'Arnab': 'Student1'}, axis='columns')
      
    
2.3.3 Accessing Elements through Indexing and Slicing
  • Label-Based Indexing ( .loc[] ):
      
        >>> ResultDF.loc['Science'] # Accesses a row as a Series
        >>> ResultDF.loc[:, 'Arnab'] # Accesses a column as a Series
      
    
  • Boolean Indexing: Filters data based on conditions.
      
      >>> ResultDF.loc['Maths'] > 90
    
    
  • Slicing: Slicing in DataFrames is inclusive of both start and end values.
      
      >>> ResultDF.loc['Maths':'Science', 'Arnab':'Samridhi']
    
    
2.3.4 Joining and Concatenating DataFrames

The .append() method is used to append rows of one DataFrame to another.

Key Parameters:

  • sort=True : Sorts column labels alphabetically.
  • verify_integrity=True : Raises an error if there are duplicate row labels.
  • ignore_index=True : Re-indexes the resulting DataFrame from 0 to N-1.
  
  >>> dFrame1 = dFrame1.append(dFrame2, ignore_index=True)

2.3.5 Attributes of DataFrames
Attribute Purpose Example Output
index Displays row labels Index(['GeoArea', 'VeryDense'], dtype='object')
columns Displays column labels Index(['Assam', 'Kerala'], dtype='object')
dtypes Displays data type of each column Assam: int64, Delhi: float64
values Returns values as a 2D NumPy ndarray array([[78438, 38852], [2797, 1663]])
shape Returns a tuple representing dimensionality (rows, columns) (4, 3)
size Returns total number of elements 12
T Transposes rows and columns Swaps row indices with column headers
2.4 Importing and Exporting Data between CSV Files and DataFrames
2.4.1 Importing a CSV File

The read_csv() function loads data from a CSV file into a DataFrame.

  
  >>> marks = pd.read_csv("C:/NCERT/ResultData.csv", sep=",", header=0)

Parameters:

  • sep : Specifies the delimiter (default is comma).
  • header : Specifies the row number to use as column names (default is 0).
  • names : Allows custom column names to be passed as a list.
2.4.2 Exporting to a CSV File

The to_csv() method writes a DataFrame to a CSV or \text file.

  
  >>> ResultDF.to_csv('C:/NCERT/resultout.csv', sep=',', index=False)

Parameters:

  • index=False : Prevents row index labels from being written to the file.
  • header=False : Prevents column headers from being written to the file.
2.5 Pandas Series vs NumPy ndarray
Feature Pandas Series NumPy ndarray
Index Type Supports custom labelled indices (numbers or letters) Accessed strictly by integer positions starting from 0
Alignment Automatically aligns data based on labels; generates NaN for mismatches Requires matching shapes; operations fail if arrays are unaligned
Memory Requires more memory due to index mapping metadata Highly memory-efficient