GPandas

Label-based Indexing (Loc)

Access DataFrame data using row labels and column names with Loc()

The Loc() accessor provides label-based indexing for DataFrames, allowing you to access data using row labels and column names.

Overview

Loc() provides intuitive data access by label:

MethodDescriptionReturns
.At(rowLabel, colName)Single valueany, error
.Row(rowLabel)Single row*DataFrame, error
.Rows(rowLabels)Multiple rows*DataFrame, error
.Col(colName)Single column*Series, error
.Cols(colNames)Multiple columns*DataFrame, error

Accessing Loc

Get the LocIndexer from a DataFrame:

df, _ := gp.Read_csv("data.csv")

// Access the Loc indexer
locIndexer := df.Loc()

// Chain methods
value, _ := df.Loc().At("0", "name")

At() - Single Value Access

Retrieve a single value by row label and column name.

Function Signature

func (l *LocIndexer) At(rowLabel string, columnName string) (any, error)

Parameters

ParameterTypeDescription
rowLabelstringRow index label
columnNamestringColumn name

Example

package main

import (
    "fmt"
    "log"

    "github.com/apoplexi24/gpandas"
)

func main() {
    gp := gpandas.GoPandas{}
    df, _ := gp.Read_csv("employees.csv")
    
    // Access single value at row "0", column "name"
    name, err := df.Loc().At("0", "name")
    if err != nil {
        log.Fatalf("Access failed: %v", err)
    }
    fmt.Printf("First employee name: %v\n", name)
    
    // Access salary for row "2"
    salary, err := df.Loc().At("2", "salary")
    if err != nil {
        log.Fatalf("Access failed: %v", err)
    }
    fmt.Printf("Third employee salary: %v\n", salary)
}

Data Flow


Row() - Single Row Access

Retrieve a single row as a new DataFrame.

Function Signature

func (l *LocIndexer) Row(rowLabel string) (*DataFrame, error)

Example

// Get the row with label "2"
row, err := df.Loc().Row("2")
if err != nil {
    log.Fatalf("Row access failed: %v", err)
}

fmt.Println("Row 2:")
fmt.Println(row.String())

Output

Row 2:
+---------+-------------+--------+
| name    | department  | salary |
+---------+-------------+--------+
| Charlie | Engineering | 92000  |
+---------+-------------+--------+
[1 rows x 3 columns]

Rows() - Multiple Rows Access

Retrieve multiple rows by their labels as a new DataFrame.

Function Signature

func (l *LocIndexer) Rows(rowLabels []string) (*DataFrame, error)

Example

// Get rows with labels "0", "2", and "3"
rows, err := df.Loc().Rows([]string{"0", "2", "3"})
if err != nil {
    log.Fatalf("Rows access failed: %v", err)
}

fmt.Println("Selected Rows:")
fmt.Println(rows.String())

Output

Selected Rows:
+---------+-------------+--------+
| name    | department  | salary |
+---------+-------------+--------+
| Alice   | Engineering | 85000  |
| Charlie | Engineering | 92000  |
| Diana   | Sales       | 68000  |
+---------+-------------+--------+
[3 rows x 3 columns]

Selection Visualization


Col() - Single Column Access

Retrieve a single column as a Series reference.

Function Signature

func (l *LocIndexer) Col(columnName string) (*collection.Series, error)

Example

// Get the "salary" column as a Series
salarySeries, err := df.Loc().Col("salary")
if err != nil {
    log.Fatalf("Column access failed: %v", err)
}

// Work with the Series
fmt.Printf("Salary column has %d entries\n", salarySeries.Len())

// Access individual values
for i := 0; i < salarySeries.Len(); i++ {
    val, _ := salarySeries.At(i)
    fmt.Printf("  Row %d: %v\n", i, val)
}

Output

Salary column has 4 entries
  Row 0: 85000
  Row 1: 72000
  Row 2: 92000
  Row 3: 68000

Cols() - Multiple Columns Access

Retrieve multiple columns as a new DataFrame.

Function Signature

func (l *LocIndexer) Cols(columnNames []string) (*DataFrame, error)

Example

// Get "name" and "salary" columns
subset, err := df.Loc().Cols([]string{"name", "salary"})
if err != nil {
    log.Fatalf("Columns access failed: %v", err)
}

fmt.Println("Name and Salary columns:")
fmt.Println(subset.String())

Output

Name and Salary columns:
+---------+--------+
| name    | salary |
+---------+--------+
| Alice   | 85000  |
| Bob     | 72000  |
| Charlie | 92000  |
| Diana   | 68000  |
+---------+--------+
[4 rows x 2 columns]

Custom Index Labels

By default, DataFrames have string index labels "0", "1", "2", etc. You can set custom labels:

Setting Custom Index

package main

import (
    "fmt"

    "github.com/apoplexi24/gpandas"
)

func main() {
    gp := gpandas.GoPandas{}
    df, _ := gp.Read_csv("employees.csv")
    
    // Set custom index labels
    err := df.SetIndex([]string{"emp_001", "emp_002", "emp_003", "emp_004"})
    if err != nil {
        panic(err)
    }
    
    // Now access using custom labels
    alice, _ := df.Loc().Row("emp_001")
    fmt.Println("Employee 001:")
    fmt.Println(alice.String())
    
    // Access specific value
    salary, _ := df.Loc().At("emp_003", "salary")
    fmt.Printf("Employee 003 salary: %v\n", salary)
}

Resetting Index

// Reset to default numeric index
df.ResetIndex()

// Now use "0", "1", "2", ... again
row, _ := df.Loc().Row("0")

Comparison: Loc vs Select

FeatureLoc()Select()
Row accessYesNo
Column accessYesYes
Single valueYes (.At())No
Returns SeriesYes (.Col())No (always DataFrame)
Index preservationYesYes

When to Use Loc

// Use Loc for row-based access
row, _ := df.Loc().Row("5")
value, _ := df.Loc().At("5", "name")

// Use Loc for column Series
series, _ := df.Loc().Col("salary")

When to Use Select

// Use Select for simple column extraction
subset, _ := df.Select("name", "salary", "department")

Method Summary

Error Handling

ErrorCauseSolution
"DataFrame is nil"Operating on nil DataFrameInitialize DataFrame first
"row label 'X' not found in index"Invalid row labelVerify label exists in Index
"column 'X' not found"Invalid column nameCheck column exists

Example

value, err := df.Loc().At("invalid_label", "name")
if err != nil {
    // Error: "row label 'invalid_label' not found in index"
    log.Printf("Access error: %v", err)
}

Thread Safety

All Loc() methods use read locks (RLock) for thread-safe concurrent access:

var wg sync.WaitGroup

// Safe concurrent reads
for i := 0; i < 10; i++ {
    wg.Add(1)
    go func(id int) {
        defer wg.Done()
        
        // Multiple goroutines can read simultaneously
        value, _ := df.Loc().At(fmt.Sprintf("%d", id%4), "name")
        fmt.Printf("Goroutine %d read: %v\n", id, value)
    }(i)
}

wg.Wait()

See Also

On this page