<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: KX</title>
    <description>The latest articles on DEV Community by KX (@godzilla_dev).</description>
    <link>https://dev.to/godzilla_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4013220%2Fc2b22d7b-7c44-455b-acce-5c00f658e169.jpg</url>
      <title>DEV Community: KX</title>
      <link>https://dev.to/godzilla_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/godzilla_dev"/>
    <language>en</language>
    <item>
      <title>godzilla.dev - AI Quant Trader Series - Day 8 - What is High Frequency Trading?</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:38:27 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-8-what-is-high-frequency-trading-1240</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-8-what-is-high-frequency-trading-1240</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_8/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_8/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 8&lt;/p&gt;

&lt;p&gt;AI × Quant Trader Series — Day 8¶&lt;br&gt;
What is High Frequency Trading?¶&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: basic programming, financial markets&lt;br&gt;
Focus: engineering intuition, system architecture (not trading strategies)&lt;/p&gt;

&lt;p&gt;Part 1: Introduction¶&lt;br&gt;
When people hear High Frequency Trading (HFT), they often imagine computers buying and selling stocks in microseconds.&lt;/p&gt;

&lt;p&gt;While speed is certainly important, it is not the essence of HFT.&lt;/p&gt;

&lt;p&gt;High Frequency Trading is the engineering discipline of building trading systems capable of:&lt;/p&gt;

&lt;p&gt;Processing market data&lt;br&gt;
Making trading decisions&lt;br&gt;
Managing risk&lt;br&gt;
Executing orders&lt;br&gt;
all within extremely tight latency constraints.&lt;/p&gt;

&lt;p&gt;At its core, HFT combines:&lt;/p&gt;

&lt;p&gt;Computer Science&lt;br&gt;
Distributed Systems&lt;br&gt;
Networking&lt;br&gt;
Operating Systems&lt;br&gt;
Market Microstructure&lt;br&gt;
Quantitative Finance&lt;br&gt;
Modern exchanges are software systems.&lt;/p&gt;

&lt;p&gt;The competition is no longer between traders.&lt;/p&gt;

&lt;p&gt;It is between software architectures.&lt;/p&gt;

&lt;p&gt;Part 2: Why High Frequency Trading Exists¶&lt;br&gt;
Electronic markets continuously generate enormous amounts of information.&lt;/p&gt;

&lt;p&gt;Every second, exchanges publish:&lt;/p&gt;

&lt;p&gt;Order submissions&lt;br&gt;
Order cancellations&lt;br&gt;
Trade executions&lt;br&gt;
Quote updates&lt;br&gt;
Every market event may represent a trading opportunity.&lt;/p&gt;

&lt;p&gt;The challenge is simple:&lt;/p&gt;

&lt;p&gt;Who can react first?&lt;br&gt;
The first system to detect an opportunity and submit an order usually captures the available liquidity.&lt;/p&gt;

&lt;p&gt;Milliseconds matter.&lt;/p&gt;

&lt;p&gt;Sometimes even microseconds.&lt;/p&gt;

&lt;p&gt;Part 3: The HFT Pipeline¶&lt;br&gt;
A modern HFT system is usually organized as a processing pipeline.&lt;/p&gt;

&lt;p&gt;Exchange&lt;br&gt;
│&lt;br&gt;
Market Data Feed&lt;br&gt;
│&lt;br&gt;
Market Data Decoder&lt;br&gt;
│&lt;br&gt;
Shared Memory&lt;br&gt;
│&lt;br&gt;
Trading Strategy&lt;br&gt;
│&lt;br&gt;
Risk Engine&lt;br&gt;
│&lt;br&gt;
Order Manager&lt;br&gt;
│&lt;br&gt;
Exchange Gateway&lt;br&gt;
│&lt;br&gt;
Exchange&lt;br&gt;
Each component performs one specialized task.&lt;/p&gt;

&lt;p&gt;Together they create a deterministic low-latency trading system.&lt;/p&gt;

&lt;p&gt;Part 4: Core Components¶&lt;br&gt;
4.1 Market Data¶&lt;br&gt;
Everything begins with market data.&lt;/p&gt;

&lt;p&gt;Exchanges continuously publish information such as:&lt;/p&gt;

&lt;p&gt;Best bid&lt;br&gt;
Best ask&lt;br&gt;
Trades&lt;br&gt;
Order book updates&lt;br&gt;
The market data engine decodes these messages and distributes them to downstream components.&lt;/p&gt;

&lt;p&gt;The faster this happens, the sooner strategies can react.&lt;/p&gt;

&lt;p&gt;4.2 Trading Strategy¶&lt;br&gt;
The strategy consumes market events and determines whether to:&lt;/p&gt;

&lt;p&gt;Buy&lt;br&gt;
Sell&lt;br&gt;
Cancel&lt;br&gt;
Modify existing orders&lt;br&gt;
Strategies can include:&lt;/p&gt;

&lt;p&gt;Market Making&lt;br&gt;
Statistical Arbitrage&lt;br&gt;
Cross-Exchange Arbitrage&lt;br&gt;
ETF Arbitrage&lt;br&gt;
Trend Following&lt;br&gt;
The strategy itself is often surprisingly small.&lt;/p&gt;

&lt;p&gt;Most engineering effort lies in the surrounding infrastructure.&lt;/p&gt;

&lt;p&gt;4.3 Risk Management¶&lt;br&gt;
Every order passes through risk control before reaching the exchange.&lt;/p&gt;

&lt;p&gt;Typical checks include:&lt;/p&gt;

&lt;p&gt;Position limits&lt;br&gt;
Exposure limits&lt;br&gt;
Price validation&lt;br&gt;
Fat-finger protection&lt;br&gt;
Kill switches&lt;br&gt;
A fast trading system without risk management is simply a fast way to lose money.&lt;/p&gt;

&lt;p&gt;4.4 Order Management¶&lt;br&gt;
The Order Management System (OMS) tracks:&lt;/p&gt;

&lt;p&gt;Active orders&lt;br&gt;
Filled orders&lt;br&gt;
Cancelled orders&lt;br&gt;
Positions&lt;br&gt;
It provides a consistent view of the trading state across the entire system.&lt;/p&gt;

&lt;p&gt;4.5 Exchange Gateway¶&lt;br&gt;
Finally, orders are transmitted through exchange-specific gateways.&lt;/p&gt;

&lt;p&gt;Each exchange has its own:&lt;/p&gt;

&lt;p&gt;Protocol&lt;br&gt;
Message format&lt;br&gt;
Authentication&lt;br&gt;
Session management&lt;br&gt;
The gateway hides these implementation details from the strategy.&lt;/p&gt;

&lt;p&gt;Part 5: Why Latency Matters¶&lt;br&gt;
Suppose two firms observe the same arbitrage opportunity.&lt;/p&gt;

&lt;p&gt;Firm A reacts in:&lt;/p&gt;

&lt;p&gt;20 μs&lt;br&gt;
Firm B reacts in:&lt;/p&gt;

&lt;p&gt;150 μs&lt;br&gt;
Both systems discovered the same opportunity.&lt;/p&gt;

&lt;p&gt;Only one receives the execution.&lt;/p&gt;

&lt;p&gt;The opportunity disappears immediately after the first successful order.&lt;/p&gt;

&lt;p&gt;This is why HFT engineers spend enormous effort reducing latency across every component of the system.&lt;/p&gt;

&lt;p&gt;Part 6: Software Engineering Challenges¶&lt;br&gt;
Building an HFT platform is primarily a systems engineering problem.&lt;/p&gt;

&lt;p&gt;Common challenges include:&lt;/p&gt;

&lt;p&gt;Memory Management¶&lt;br&gt;
Avoid unnecessary allocations.&lt;/p&gt;

&lt;p&gt;Reuse objects whenever possible.&lt;/p&gt;

&lt;p&gt;Lock-Free Programming¶&lt;br&gt;
Traditional mutexes introduce unpredictable latency.&lt;/p&gt;

&lt;p&gt;Many production systems rely on:&lt;/p&gt;

&lt;p&gt;Atomic operations&lt;br&gt;
Ring buffers&lt;br&gt;
Lock-free queues&lt;br&gt;
Shared Memory¶&lt;br&gt;
Passing data between processes through sockets is expensive.&lt;/p&gt;

&lt;p&gt;Shared memory allows multiple processes to access market data with almost zero copying.&lt;/p&gt;

&lt;p&gt;CPU Cache Optimization¶&lt;br&gt;
Modern CPUs are significantly faster than main memory.&lt;/p&gt;

&lt;p&gt;Efficient cache usage often produces larger performance gains than algorithmic optimization.&lt;/p&gt;

&lt;p&gt;Deterministic Performance¶&lt;br&gt;
Average latency is not enough.&lt;/p&gt;

&lt;p&gt;Professional trading systems focus on:&lt;/p&gt;

&lt;p&gt;Predictable latency&lt;br&gt;
Stable execution&lt;br&gt;
Minimal jitter&lt;br&gt;
Consistency matters more than occasional speed.&lt;/p&gt;

&lt;p&gt;Part 7: HFT vs Algorithmic Trading¶&lt;br&gt;
These terms are often confused.&lt;/p&gt;

&lt;p&gt;Algorithmic Trading is a broad category covering any automated trading strategy.&lt;/p&gt;

&lt;p&gt;High Frequency Trading is a specialized subset emphasizing:&lt;/p&gt;

&lt;p&gt;Extremely low latency&lt;br&gt;
High message throughput&lt;br&gt;
Very short holding periods&lt;br&gt;
Continuous market interaction&lt;br&gt;
Every HFT system is algorithmic trading.&lt;/p&gt;

&lt;p&gt;Not every algorithmic trading system is HFT.&lt;/p&gt;

&lt;p&gt;Part 8: Common Misconceptions¶&lt;br&gt;
HFT is not Artificial Intelligence¶&lt;br&gt;
Most HFT systems rely on:&lt;/p&gt;

&lt;p&gt;Market microstructure&lt;br&gt;
Statistical models&lt;br&gt;
Rule-based execution&lt;br&gt;
Machine learning is only one possible component.&lt;/p&gt;

&lt;p&gt;HFT is not only about faster hardware¶&lt;br&gt;
Buying expensive servers does not automatically create a low-latency platform.&lt;/p&gt;

&lt;p&gt;Architecture matters more than hardware.&lt;/p&gt;

&lt;p&gt;Good software consistently outperforms poor software running on expensive machines.&lt;/p&gt;

&lt;p&gt;HFT is not only for large institutions¶&lt;br&gt;
Open-source infrastructure has dramatically reduced the barrier to entry.&lt;/p&gt;

&lt;p&gt;Independent quantitative researchers can now build professional-grade trading systems using commodity hardware.&lt;/p&gt;

&lt;p&gt;Part 9: Where godzilla.dev Fits¶&lt;br&gt;
Building an HFT platform from scratch requires implementing:&lt;/p&gt;

&lt;p&gt;Market data processing&lt;br&gt;
Shared memory communication&lt;br&gt;
Order management&lt;br&gt;
Risk management&lt;br&gt;
Exchange gateways&lt;br&gt;
Strategy framework&lt;br&gt;
Monitoring&lt;br&gt;
Performance optimization&lt;br&gt;
These components represent years of engineering effort.&lt;/p&gt;

&lt;p&gt;godzilla.dev provides an open-source ultra-low latency trading framework designed specifically for modern electronic markets.&lt;/p&gt;

&lt;p&gt;Instead of rebuilding infrastructure repeatedly, quantitative developers can focus on strategy research while relying on a modular, production-oriented architecture.&lt;/p&gt;

&lt;p&gt;Part 10: Key Takeaways¶&lt;br&gt;
High Frequency Trading is fundamentally a systems engineering discipline.&lt;/p&gt;

&lt;p&gt;Its objective is not simply "trading faster."&lt;/p&gt;

&lt;p&gt;Instead, it focuses on building reliable, deterministic, and ultra-low latency software capable of processing millions of market events while maintaining strict risk controls.&lt;/p&gt;

&lt;p&gt;Understanding HFT requires knowledge of:&lt;/p&gt;

&lt;p&gt;Market Microstructure&lt;br&gt;
Operating Systems&lt;br&gt;
Computer Networks&lt;br&gt;
Concurrent Programming&lt;br&gt;
Low-Latency Architecture&lt;br&gt;
Trading strategies may evolve.&lt;/p&gt;

&lt;p&gt;The underlying engineering principles remain remarkably consistent.&lt;/p&gt;

&lt;p&gt;What's Next?¶&lt;br&gt;
The following articles explore each component in greater depth:&lt;/p&gt;

&lt;p&gt;What is Market Microstructure?&lt;br&gt;
What is an Order Book?&lt;br&gt;
What is Shared Memory IPC?&lt;br&gt;
What is a Matching Engine?&lt;br&gt;
What is an Order Management System (OMS)?&lt;br&gt;
What is a Risk Engine?&lt;br&gt;
Lock-Free Programming&lt;br&gt;
Event-Driven Architecture&lt;br&gt;
Building Low-Latency Trading Systems&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI Quant Trader Series — Day 7</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:37:01 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/ai-x-quant-trader-series-day-7-2jj5</link>
      <guid>https://dev.to/godzilla_dev/ai-x-quant-trader-series-day-7-2jj5</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_7/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_7/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 7&lt;/p&gt;

&lt;p&gt;The Swiss Army Knife of Linear Models: Lasso Regression¶&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: basic linear algebra, Python, NumPy&lt;br&gt;
Focus: engineering intuition, quant usage (not ML hype)&lt;/p&gt;

&lt;p&gt;Part 1: Introduction to Regularized Linear Models¶&lt;br&gt;
We now move from data processing to one of the most important modeling tools in quantitative trading and applied machine learning: regularized linear models.&lt;/p&gt;

&lt;p&gt;In real-world financial modeling, the main difficulty is rarely computation. Instead, it is almost always structure:&lt;/p&gt;

&lt;p&gt;Too many features&lt;br&gt;
Strong multicollinearity&lt;br&gt;
Limited samples&lt;br&gt;
High noise-to-signal ratio&lt;br&gt;
A plain linear regression model can fit the data extremely well in-sample, yet fail catastrophically out-of-sample.&lt;/p&gt;

&lt;p&gt;This is where Lasso regression becomes indispensable.&lt;/p&gt;

&lt;p&gt;Part 2: From Linear Regression to Lasso¶&lt;br&gt;
2.1 Ordinary Least Squares (OLS)¶&lt;br&gt;
The objective function of ordinary least squares is:&lt;/p&gt;

&lt;p&gt;OLS attempts to minimize prediction error only.&lt;br&gt;
It places no constraint on model complexity.&lt;/p&gt;

&lt;p&gt;As a result:&lt;/p&gt;

&lt;p&gt;Coefficients become unstable when features are correlated&lt;br&gt;
Noise features receive non-zero weights&lt;br&gt;
Overfitting is almost guaranteed in high-dimensional settings&lt;br&gt;
2.2 Why Regularization Is Necessary¶&lt;br&gt;
In quantitative finance, feature sets often include:&lt;/p&gt;

&lt;p&gt;Dozens of technical indicators&lt;br&gt;
Overlapping factors&lt;br&gt;
Lagged signals&lt;br&gt;
Many of these features carry redundant or spurious information.&lt;/p&gt;

&lt;p&gt;Regularization explicitly penalizes complexity, forcing the model to prefer simpler and more stable solutions.&lt;/p&gt;

&lt;p&gt;Part 3: Lasso Regression — Core Idea¶&lt;br&gt;
3.1 Objective Function¶&lt;br&gt;
Lasso (Least Absolute Shrinkage and Selection Operator) modifies OLS by adding an L1 penalty:&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;The first term measures fit quality&lt;br&gt;
The second term penalizes coefficient magnitude&lt;br&gt;
controls the strength of regularization&lt;br&gt;
3.2 What Makes Lasso Different¶&lt;br&gt;
Unlike Ridge regression (L2 regularization), Lasso drives some coefficients exactly to zero.&lt;/p&gt;

&lt;p&gt;This leads to:&lt;/p&gt;

&lt;p&gt;Automatic feature selection&lt;br&gt;
Sparse models&lt;br&gt;
Improved interpretability&lt;br&gt;
From an engineering perspective:&lt;/p&gt;

&lt;p&gt;Lasso is not just a regression model — it is a structured filter.&lt;br&gt;
Part 4: Intuition — Why Lasso Produces Sparsity¶&lt;br&gt;
The L1 penalty creates a sharp constraint geometry.&lt;br&gt;
When optimization occurs under this constraint, solutions naturally land on coordinate axes.&lt;/p&gt;

&lt;p&gt;The practical consequence is simple:&lt;/p&gt;

&lt;p&gt;Unimportant features are dropped entirely.&lt;br&gt;
This behavior is extremely valuable in quant trading, where fewer signals often outperform noisy combinations.&lt;/p&gt;

&lt;p&gt;Part 5: Implementing Lasso in Python¶&lt;br&gt;
We now implement Lasso using scikit-learn.&lt;/p&gt;

&lt;p&gt;Imports¶&lt;br&gt;
import numpy as np&lt;br&gt;
import pandas as pd&lt;br&gt;
from sklearn.linear_model import Lasso&lt;br&gt;
from sklearn.preprocessing import StandardScaler&lt;br&gt;
5.1 Generate Example Data¶&lt;br&gt;
import numpy as np&lt;/p&gt;

&lt;p&gt;np.random.seed(42)&lt;/p&gt;

&lt;p&gt;X = np.random.randn(100, 10)&lt;br&gt;
true_beta = np.array([3, 0, 0, 1.5, 0, 0, 0, 2, 0, 0])&lt;br&gt;
y = X @ true_beta + np.random.randn(100) * 0.5&lt;br&gt;
5.2 Standardize Features¶&lt;br&gt;
from sklearn.preprocessing import StandardScaler&lt;/p&gt;

&lt;p&gt;scaler = StandardScaler()&lt;br&gt;
X_scaled = scaler.fit_transform(X)&lt;br&gt;
5.3 Fit the Lasso Model¶&lt;/p&gt;

&lt;p&gt;from sklearn.linear_model import Lasso&lt;br&gt;
import pandas as pd&lt;/p&gt;

&lt;p&gt;lasso = Lasso(alpha=0.1)&lt;br&gt;
lasso.fit(X_scaled, y)&lt;br&gt;
pd.Series(lasso.coef_)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;0    2.85&lt;br&gt;
1    0.00&lt;br&gt;
2    0.00&lt;br&gt;
3    1.42&lt;br&gt;
4    0.00&lt;br&gt;
5    0.00&lt;br&gt;
6    0.00&lt;br&gt;
7    1.95&lt;br&gt;
8    0.00&lt;br&gt;
9    0.00&lt;br&gt;
dtype: float64&lt;br&gt;
Noise features are eliminated automatically, while true signals are retained.&lt;/p&gt;

&lt;p&gt;Part 6: The Role of Alpha (λ)¶&lt;br&gt;
6.1 Effect of Regularization Strength¶&lt;br&gt;
Small α → weak regularization → overfitting&lt;/p&gt;

&lt;p&gt;Large α → aggressive shrinkage → underfitting&lt;/p&gt;

&lt;p&gt;for a in [0.01, 0.1, 1.0]:&lt;br&gt;
    model = Lasso(alpha=a)&lt;br&gt;
    model.fit(X_scaled, y)&lt;br&gt;
    print(a, (model.coef_ != 0).sum())&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;0.01 7&lt;br&gt;
0.1  3&lt;br&gt;
1.0  0&lt;/p&gt;

&lt;p&gt;6.2 Cross-Validation (Recommended)¶&lt;/p&gt;

&lt;p&gt;from sklearn.linear_model import LassoCV&lt;/p&gt;

&lt;p&gt;lasso_cv = LassoCV(cv=5)&lt;br&gt;
lasso_cv.fit(X_scaled, y)&lt;/p&gt;

&lt;p&gt;lasso_cv.alpha_&lt;br&gt;
lasso_cv.coef_&lt;br&gt;
Cross-validation improves robustness across different market regimes.&lt;/p&gt;

&lt;p&gt;Part 7: Limitations of Lasso¶&lt;br&gt;
Lasso is not universally optimal:&lt;/p&gt;

&lt;p&gt;Performs poorly when features are highly correlated&lt;/p&gt;

&lt;p&gt;Cannot model non-linear interactions&lt;/p&gt;

&lt;p&gt;Sensitive to outliers&lt;/p&gt;

&lt;p&gt;Common remedies include:&lt;/p&gt;

&lt;p&gt;Elastic Net (L1 + L2)&lt;/p&gt;

&lt;p&gt;PCA + Lasso&lt;/p&gt;

&lt;p&gt;Lasso for feature selection followed by non-linear models&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 6</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:26:22 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-6-41h3</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-6-41h3</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_6/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_6/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 6&lt;/p&gt;

&lt;p&gt;The Swiss Army Knife of Python Data Processing: pandas"¶&lt;br&gt;
Part 2: Rapid Advancement¶&lt;br&gt;
In the previous article, we introduced how to create and access data in pandas using the Series and DataFrame types. In this article, we will cover how to perform operations on pandas data. Once you’ve mastered these operations, you’ll be able to handle most data processing tasks.&lt;/p&gt;

&lt;p&gt;First, let’s import the modules we’ll be using in this article:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
import pandas as pd&lt;br&gt;
from pandas import Series, DataFrame&lt;br&gt;
To make the data easier to view, let’s adjust the output display width&lt;/p&gt;

&lt;p&gt;pd.set_option('display.width', 200)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Other Ways to Create Data¶
The creation of data structures is not limited to the standard forms introduced in the previous article.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, we’ll look at a few more. For example, we can create a Series with dates as its elements:&lt;/p&gt;

&lt;p&gt;dates = pd.date_range('20250101', periods=5)&lt;br&gt;
print(dates)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;DatetimeIndex(['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-04', '2025-01-05'], dtype='datetime64[ns]', freq='D')&lt;/p&gt;

&lt;p&gt;Assign this date Series as the index of a DataFrame:&lt;/p&gt;

&lt;p&gt;df = pd.DataFrame(np.random.randn(5, 4),index=dates,columns=list('ABCD'))&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;               A         B         C         D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2025-01-01 -1.119762 -0.088336  1.921095  1.158499&lt;br&gt;
2025-01-02 -0.250627  0.271175 -0.505430 -1.490358&lt;br&gt;
2025-01-03  0.710884 -1.478697  0.537757  1.448547&lt;br&gt;
2025-01-04 -1.658607 -0.364456  0.196627  0.881224&lt;br&gt;
2025-01-05  0.347936  0.312740 -0.199889  2.881074&lt;/p&gt;

&lt;p&gt;Any object that can be converted into a Series can be used to create a DataFrame:&lt;/p&gt;

&lt;p&gt;df2 = pd.DataFrame({ 'A' : 1., 'B': pd.Timestamp('20250214'), 'C': pd.Series(1.6,index=list(range(4)),dtype='float64'), 'D' : np.array([4] * 4, dtype='int64'), 'E' : 'hello pandas!' })&lt;br&gt;
print(df2)&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; A          B    C  D              E
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;0  1.0 2025-02-14  1.6  4  hello pandas!&lt;br&gt;
1  1.0 2025-02-14  1.6  4  hello pandas!&lt;br&gt;
2  1.0 2025-02-14  1.6  4  hello pandas!&lt;br&gt;
3  1.0 2025-02-14  1.6  4  hello pandas!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Viewing Data¶
In most cases, data is not generated by the analysts themselves but obtained through data APIs, external files, or other sources.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here, we’ll use a dataset retrieved from binance rest api as an example:&lt;/p&gt;

&lt;h1&gt;
  
  
  pip install pandas requests python-dateutil
&lt;/h1&gt;

&lt;p&gt;import requests&lt;br&gt;
import pandas as pd&lt;br&gt;
from dateutil import parser&lt;/p&gt;

&lt;p&gt;symbol = "BTCUSDT"  # REST 接口不带斜杠&lt;br&gt;
interval = "1d"&lt;/p&gt;

&lt;p&gt;start = "2025-01-01 00:00:00"&lt;br&gt;
end   = "2025-02-01 00:00:00"&lt;/p&gt;

&lt;p&gt;start_ms = int(parser.isoparse(start).timestamp() * 1000)&lt;br&gt;
end_ms   = int(parser.isoparse(end).timestamp() * 1000)&lt;/p&gt;

&lt;p&gt;url = "&lt;a href="https://api.binance.com/api/v3/klines" rel="noopener noreferrer"&gt;https://api.binance.com/api/v3/klines&lt;/a&gt;"&lt;br&gt;
params = {&lt;br&gt;
    "symbol": symbol,&lt;br&gt;
    "interval": interval,&lt;br&gt;
    "startTime": start_ms,&lt;br&gt;
    "endTime": end_ms,&lt;br&gt;
    "limit": 1000&lt;br&gt;
}&lt;br&gt;
r = requests.get(url, params=params, timeout=15)&lt;br&gt;
r.raise_for_status()&lt;br&gt;
data = r.json()&lt;/p&gt;

&lt;h1&gt;
  
  
  返回每一行：
&lt;/h1&gt;

&lt;h1&gt;
  
  
  [
&lt;/h1&gt;

&lt;h1&gt;
  
  
  0 open time, 1 open, 2 high, 3 low, 4 close, 5 volume,
&lt;/h1&gt;

&lt;h1&gt;
  
  
  6 close time, 7 quote asset volume, 8 number of trades,
&lt;/h1&gt;

&lt;h1&gt;
  
  
  9 taker buy base volume, 10 taker buy quote volume, 11 ignore
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ]
&lt;/h1&gt;

&lt;p&gt;df = pd.DataFrame(data, columns=[&lt;br&gt;
    "open_time","open","high","low","close","volume",&lt;br&gt;
    "close_time","quote_vol","trades","taker_base","taker_quote","ignore"&lt;br&gt;
])&lt;/p&gt;

&lt;h1&gt;
  
  
  转数值
&lt;/h1&gt;

&lt;p&gt;for col in ["open","high","low","close","volume","quote_vol","taker_base","taker_quote"]:&lt;br&gt;
    df[col] = pd.to_numeric(df[col], errors="coerce")&lt;/p&gt;

&lt;h1&gt;
  
  
  只保留核心列，并用UTC日期索引
&lt;/h1&gt;

&lt;p&gt;df["date_utc"] = pd.to_datetime(df["open_time"], unit="ms", utc=True).dt.date&lt;br&gt;
df = df[["open","high","low","close","volume","date_utc"]].set_index("date_utc").sort_index()&lt;/p&gt;

&lt;p&gt;print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             open       high        low      close        volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;date_utc&lt;br&gt;&lt;br&gt;
2025-01-01   93576.00   95151.15   92888.00   94591.79  10373.326130&lt;br&gt;
2025-01-02   94591.78   97839.50   94392.00   96984.79  21970.489480&lt;br&gt;
2025-01-03   96984.79   98976.91   96100.01   98174.18  15253.829360&lt;br&gt;
2025-01-04   98174.17   98778.43   97514.79   98220.50   8990.056510&lt;br&gt;
2025-01-05   98220.51   98836.85   97276.79   98363.61   8095.637230&lt;br&gt;
2025-01-06   98363.61  102480.00   97920.00  102235.60  25263.433750&lt;br&gt;
2025-01-07  102235.60  102724.38   96181.81   96954.61  32059.875370&lt;br&gt;
2025-01-08   96954.60   97268.65   92500.90   95060.61  33704.678940&lt;br&gt;
2025-01-09   95060.61   95382.32   91203.67   92552.49  34544.836850&lt;br&gt;
2025-01-10   92552.49   95836.00   92206.02   94726.11  31482.864240&lt;br&gt;
2025-01-11   94726.10   95050.94   93831.73   94599.99   7047.904300&lt;br&gt;
2025-01-12   94599.99   95450.10   93711.19   94545.06   8606.866220&lt;br&gt;
2025-01-13   94545.07   95940.00   89256.69   94536.10  42619.564230&lt;br&gt;
2025-01-14   94536.11   97371.00   94346.22   96560.86  27846.617530&lt;br&gt;
2025-01-15   96560.85  100681.94   96500.00  100497.35  30509.991790&lt;br&gt;
2025-01-16  100497.35  100866.66   97335.13   99987.30  27832.853170&lt;br&gt;
2025-01-17   99987.30  105865.22   99950.77  104077.48  39171.852920&lt;br&gt;
2025-01-18  104077.47  104988.88  102277.55  104556.23  24307.829980&lt;br&gt;
2025-01-19  104556.23  106422.43   99651.60  101331.57  43397.282980&lt;br&gt;
2025-01-20  101331.57  109588.00   99550.00  102260.01  89529.231732&lt;br&gt;
2025-01-21  102260.00  107240.81  100119.04  106143.82  45941.020020&lt;br&gt;
2025-01-22  106143.82  106394.46  103339.12  103706.66  22248.692540&lt;br&gt;
2025-01-23  103706.66  106850.00  101262.28  103910.34  53953.120310&lt;br&gt;
2025-01-24  103910.35  107120.00  102750.00  104870.50  23609.240170&lt;br&gt;
2025-01-25  104870.51  105286.52  104106.09  104746.85   9068.323770&lt;br&gt;
2025-01-26  104746.86  105500.00  102520.44  102620.00   9812.512380&lt;br&gt;
2025-01-27  102620.01  103260.00   97777.77  102082.83  50758.134100&lt;br&gt;
2025-01-28  102082.83  103800.00  100272.68  101335.52  22022.057650&lt;br&gt;
2025-01-29  101335.52  104782.68  101328.01  103733.24  23155.358020&lt;br&gt;
2025-01-30  103733.25  106457.44  103278.54  104722.94  19374.074720&lt;br&gt;
2025-01-31  104722.94  106012.00  101560.00  102429.56  21983.181930&lt;/p&gt;

&lt;p&gt;Using the code above, we retrieved BTC’s daily market data for all trading days in January 2025. First, let’s check the size of the dataset:&lt;/p&gt;

&lt;p&gt;print(df.shape)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;(31, 5)&lt;/p&gt;

&lt;p&gt;We can see there are 31 rows, which means we fetched 31 records. Each record has 5 fields.&lt;/p&gt;

&lt;p&gt;Now let’s preview the data: DataFrame.head() and DataFrame.tail() show the first five and last five rows, respectively. To change the number of rows displayed, pass a number in the parentheses.&lt;/p&gt;

&lt;p&gt;print("Head of this DataFrame:")&lt;br&gt;
print(df.head())&lt;br&gt;
print("Tail of this DataFrame:")&lt;br&gt;
print(df.tail(3))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Head of this DataFrame:&lt;br&gt;
                open      high       low     close       volume&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-01  93576.00  95151.15  92888.00  94591.79  10373.32613&lt;br&gt;
2025-01-02  94591.78  97839.50  94392.00  96984.79  21970.48948&lt;br&gt;
2025-01-03  96984.79  98976.91  96100.01  98174.18  15253.82936&lt;br&gt;
2025-01-04  98174.17  98778.43  97514.79  98220.50   8990.05651&lt;br&gt;
2025-01-05  98220.51  98836.85  97276.79  98363.61   8095.63723&lt;br&gt;
Tail of this DataFrame:&lt;br&gt;
                 open       high        low      close       volume&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-29  101335.52  104782.68  101328.01  103733.24  23155.35802&lt;br&gt;
2025-01-30  103733.25  106457.44  103278.54  104722.94  19374.07472&lt;br&gt;
2025-01-31  104722.94  106012.00  101560.00  102429.56  21983.18193&lt;/p&gt;

&lt;p&gt;DataFrame.describe() provides statistical summaries for the purely numeric data in the DataFrame.&lt;/p&gt;

&lt;p&gt;print(df.describe())&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            open           high            low          close        volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;count      31.000000      31.000000      31.000000      31.000000     31.000000&lt;br&gt;
mean    99750.482258  101877.524839   97835.769032  100036.080645  27888.217365&lt;br&gt;
std      4148.002200    4544.879400    4050.642975    4011.242254  17319.976611&lt;br&gt;
min     92552.490000   95050.940000   89256.690000   92552.490000   7047.904300&lt;br&gt;
25%     95810.730000   97605.250000   94369.110000   96757.735000  17313.952040&lt;br&gt;
50%    100497.350000  102724.380000   97777.770000  101331.570000  24307.829980&lt;br&gt;
75%    103719.955000  105938.610000  101295.145000  103719.950000  34124.757895&lt;br&gt;
max    106143.820000  109588.000000  104106.090000  106143.820000  89529.231732&lt;/p&gt;

&lt;p&gt;Sorting the data makes it easier to inspect. A DataFrame offers two kinds of sorting.&lt;/p&gt;

&lt;p&gt;One is label-based sorting—i.e., sorting by the index (row labels) or by column names.&lt;/p&gt;

&lt;p&gt;Use DataFrame.sort_index, with axis=0 to sort by the index (rows) and axis=1 to sort by column names. You can also specify ascending or descending order.&lt;/p&gt;

&lt;p&gt;print("Order by column names, descending:")&lt;br&gt;
print(df.sort_index(axis=1, ascending=False).head())&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Order by column names, descending:&lt;br&gt;
                 volume      open       low      high     close&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-01  10373.32613  93576.00  92888.00  95151.15  94591.79&lt;br&gt;
2025-01-02  21970.48948  94591.78  94392.00  97839.50  96984.79&lt;br&gt;
2025-01-03  15253.82936  96984.79  96100.01  98976.91  98174.18&lt;br&gt;
2025-01-04   8990.05651  98174.17  97514.79  98778.43  98220.50&lt;br&gt;
2025-01-05   8095.63723  98220.51  97276.79  98836.85  98363.61&lt;/p&gt;

&lt;p&gt;The second type is value-based sorting. You can specify the column name(s) and the sort order; by default, it sorts in ascending order.&lt;/p&gt;

&lt;p&gt;print("Order by column value, ascending:")&lt;br&gt;
print(df.sort_values(by="date_utc", ascending=True).head())&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Order by column value, ascending:&lt;br&gt;
                open      high       low     close       volume&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-01  93576.00  95151.15  92888.00  94591.79  10373.32613&lt;br&gt;
2025-01-02  94591.78  97839.50  94392.00  96984.79  21970.48948&lt;br&gt;
2025-01-03  96984.79  98976.91  96100.01  98174.18  15253.82936&lt;br&gt;
2025-01-04  98174.17  98778.43  97514.79  98220.50   8990.05651&lt;br&gt;
2025-01-05  98220.51  98836.85  97276.79  98363.61   8095.63723&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data Access and Manipulation¶
3.1 Revisiting Data Access¶
In the previous section, we introduced several ways to access data in a DataFrame using loc, iloc, at, iat, ix, and [].&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here, we’ll introduce another method: using ":" to retrieve part of the rows or all of the columns.&lt;/p&gt;

&lt;p&gt;print(df.iloc[1:4][:])&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            open      high       low     close       volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;date_utc&lt;br&gt;&lt;br&gt;
2025-01-02  94591.78  97839.50  94392.00  96984.79  21970.48948&lt;br&gt;
2025-01-03  96984.79  98976.91  96100.01  98174.18  15253.82936&lt;br&gt;
2025-01-04  98174.17  98778.43  97514.79  98220.50   8990.05651&lt;/p&gt;

&lt;p&gt;We can extend the method introduced in the previous section that uses Boolean vectors to access data.&lt;/p&gt;

&lt;p&gt;This makes it very convenient to filter data. For example, we can select the rows where the closing price is above the average.&lt;/p&gt;

&lt;p&gt;print(df[df.close&amp;gt; df.close.mean()].head())&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             open       high        low      close       volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;date_utc&lt;br&gt;&lt;br&gt;
2025-01-06   98363.61  102480.00   97920.00  102235.60  25263.43375&lt;br&gt;
2025-01-15   96560.85  100681.94   96500.00  100497.35  30509.99179&lt;br&gt;
2025-01-17   99987.30  105865.22   99950.77  104077.48  39171.85292&lt;br&gt;
2025-01-18  104077.47  104988.88  102277.55  104556.23  24307.82998&lt;br&gt;
2025-01-19  104556.23  106422.43   99651.60  101331.57  43397.28298&lt;br&gt;
开启送礼物&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 5</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:24:06 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-5-32mh</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-5-32mh</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_5/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_5/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 5&lt;/p&gt;

&lt;p&gt;The Swiss Army Knife of Python Data Processing: pandas"¶&lt;br&gt;
Part 1: Introduction to Basic Data Structures¶&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introduction to Pandas¶
We've finally arrived at the module the author is most eager to introduce — and arguably the most powerful Python extension for data processing: pandas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When working with real-world financial data, a single record often contains multiple types of data. For example, a stock ticker is a string, the closing price is a float, and the trading volume is an integer. In C++, this can be handled using a container like a vector of custom structs. In Python, pandas provides high-level data structures — Series and DataFrame — that make data manipulation extremely convenient, fast, and straightforward.&lt;/p&gt;

&lt;p&gt;Note that there are some incompatibilities between different versions of pandas. Therefore, it's important to know which version you are using. Let's first check the version of pandas in your local enviroment:&lt;/p&gt;

&lt;p&gt;import pandas as pd&lt;br&gt;
pd.&lt;strong&gt;version&lt;/strong&gt;&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'2.2.3'&lt;/p&gt;

&lt;p&gt;The two main data structures in pandas are Series and DataFrame. In the next two sections, we’ll explore how to create these structures either from other data types or from scratch. But first, let’s import them along with the relevant modules:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
from pandas import Series, DataFrame&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pandas Data Structure: Series¶
Generally speaking, a Series can be thought of as a one-dimensional array. The main difference between a Series and a regular 1D array is that a Series has an index, which makes it similar to a hash (dictionary-like structure) commonly seen in programming.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2.1 Creating a Series¶&lt;br&gt;
The basic format for creating a Series is:&lt;/p&gt;

&lt;p&gt;s = Series(data, index=index, name=name)&lt;/p&gt;

&lt;p&gt;Below are a few examples of how to create a Series. Let's start by creating a Series from an array:&lt;/p&gt;

&lt;p&gt;a = np.random.randn(5)&lt;br&gt;
print("a is an array:")&lt;br&gt;
print(a)&lt;br&gt;
s = Series(a)&lt;br&gt;
print("s is a Series:")&lt;br&gt;
print(s)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a is an array:&lt;br&gt;
[ 1.35729482 -1.45138391  0.91716941 -1.24918144 -0.68685959]&lt;br&gt;
s is a Series:&lt;br&gt;
0    1.357295&lt;br&gt;
1   -1.451384&lt;br&gt;
2    0.917169&lt;br&gt;
3   -1.249181&lt;br&gt;
4   -0.686860&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;You can specify an index when creating a Series, and you can use Series.index to view the specific index values. One important thing to note is that when creating a Series from an array, the length of the specified index must match the length of the data.&lt;/p&gt;

&lt;p&gt;s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])&lt;br&gt;
print(s)&lt;br&gt;
s.index&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a   -1.898245&lt;br&gt;
b    0.172835&lt;br&gt;
c    0.779262&lt;br&gt;
d    0.289468&lt;br&gt;
e   -0.947995&lt;br&gt;
Name: my_series, dtype: float64&lt;br&gt;
my_series&lt;/p&gt;

&lt;p&gt;Another optional parameter when creating a Series is name, which allows you to assign a name to the Series. You can access it using Series.name. In a DataFrame, the name of each column becomes the name of the Series when that column is extracted individually.&lt;/p&gt;

&lt;p&gt;s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'], name='my_series')&lt;br&gt;
print(s)&lt;br&gt;
print(s.name)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a   -1.898245&lt;br&gt;
b    0.172835&lt;br&gt;
c    0.779262&lt;br&gt;
d    0.289468&lt;br&gt;
e   -0.947995&lt;br&gt;
Name: my_series, dtype: float64&lt;br&gt;
my_series&lt;/p&gt;

&lt;p&gt;A Series can also be created from a dictionary (dict):&lt;/p&gt;

&lt;p&gt;d = {'a': 0., 'b': 1, 'c': 2}&lt;br&gt;
print("d is a dict:")&lt;br&gt;
print(d)&lt;br&gt;
s = Series(d)&lt;br&gt;
print("s is a Series:")&lt;br&gt;
print(s)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;d is a dict:&lt;br&gt;
{'a': 0.0, 'c': 2, 'b': 1}&lt;br&gt;
s is a Series:&lt;br&gt;
a    0&lt;br&gt;
b    1&lt;br&gt;
c    2&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;Let’s take a look at the case where we specify an index when creating a Series from a dictionary (the index does not have to match the dictionary’s length):&lt;/p&gt;

&lt;p&gt;Series(d, index=['b', 'c', 'd', 'a'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;b     1&lt;br&gt;
c     2&lt;br&gt;
d   NaN&lt;br&gt;
a     0&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;We can observe two things:&lt;/p&gt;

&lt;p&gt;When creating a Series from a dictionary, the data is reordered to match the specified index.&lt;/p&gt;

&lt;p&gt;The length of the index does not need to match the length of the dictionary. If there are extra index labels, pandas will automatically assign them a value of NaN (Not a Number — the standard marker for missing data in pandas). If the index is shorter, only the corresponding subset of the dictionary will be used.&lt;/p&gt;

&lt;p&gt;If the data is a single value, such as the number 4, then the Series will repeat this value across all index labels:&lt;/p&gt;

&lt;p&gt;Series(4., index=['a', 'b', 'c', 'd', 'e'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    4&lt;br&gt;
b    4&lt;br&gt;
c    4&lt;br&gt;
d    4&lt;br&gt;
e    4&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;2.2 Accessing Data in a Series¶&lt;br&gt;
You can access data in a Series using index positions (like arrays), index labels (like dictionaries), and even through conditional filtering:&lt;/p&gt;

&lt;p&gt;s = Series(np.random.randn(10),index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])&lt;br&gt;
s[0]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;1.4328106520571824&lt;/p&gt;

&lt;p&gt;s[:2]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    1.432811&lt;br&gt;
b    0.120681&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;s[[2,0,4]]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;c    0.578146&lt;br&gt;
a    1.432811&lt;br&gt;
e    1.327594&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;s[['e', 'i']]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;e    1.327594&lt;br&gt;
i   -0.634347&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;s[s &amp;gt; 0.5]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    1.432811&lt;br&gt;
c    0.578146&lt;br&gt;
e    1.327594&lt;br&gt;
g    1.850783&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;'e' in s&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;True&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pandas Data Structure: DataFrame¶
Before using a DataFrame, let’s briefly go over its characteristics. A DataFrame is a two-dimensional data structure formed by combining multiple Series (column-wise). Each column, when extracted individually, is a Series. This is very similar to how data is retrieved from a SQL database. Therefore, it’s often more convenient to process a DataFrame column by column, and it's helpful for users to develop a column-oriented mindset when working with data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One of the key advantages of a DataFrame is its ability to handle columns of different data types with ease. So there's no need to think about operations like matrix inversion on a DataFrame full of floats — for such numerical tasks, it’s usually better to store the data in a NumPy matrix.&lt;/p&gt;

&lt;p&gt;3.1 Creating a DataFrame¶&lt;br&gt;
Let’s first look at how to create a DataFrame from a dictionary. A DataFrame is a 2D data structure that serves as a collection of Series. We’ll start by creating a dictionary where the values are Series, and then convert it into a DataFrame:&lt;/p&gt;

&lt;p&gt;d = {'one': Series([1., 2., 3.], index=['a', 'b', 'c']), 'two': Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}&lt;br&gt;
df = DataFrame(d)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;one  two&lt;br&gt;
a    1    1&lt;br&gt;
b    2    2&lt;br&gt;
c    3    3&lt;br&gt;
d  NaN    4&lt;/p&gt;

&lt;p&gt;You can specify the desired rows (index) and columns when creating the DataFrame. If the dictionary does not contain the corresponding elements, those entries will be filled with NaN (missing values):&lt;/p&gt;

&lt;p&gt;df = DataFrame(d, index=['r', 'd', 'a'], columns=['two', 'three'])&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;two three&lt;br&gt;
r  NaN   NaN&lt;br&gt;
d    4   NaN&lt;br&gt;
a    1   NaN&lt;/p&gt;

&lt;p&gt;You can use dataframe.index and dataframe.columns to view the rows and columns of a DataFrame. The dataframe.values attribute returns the elements of the DataFrame as a NumPy array.&lt;/p&gt;

&lt;p&gt;print("DataFrame index:")&lt;br&gt;
print(df.index)&lt;br&gt;
print("DataFrame columns:")&lt;br&gt;
print(df.columns)&lt;br&gt;
print("DataFrame values:")&lt;br&gt;
print(df.values)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;DataFrame index:&lt;br&gt;
Index([u'alpha', u'beta', u'gamma', u'delta', u'eta'], dtype='object')&lt;br&gt;
DataFrame columns:&lt;br&gt;
Index([u'a', u'b', u'c', u'd', u'e'], dtype='object')&lt;br&gt;
DataFrame values:&lt;br&gt;
[[  0.   0.   0.   0.   0.]&lt;br&gt;
 [  1.   2.   3.   4.   5.]&lt;br&gt;
 [  2.   4.   6.   8.  10.]&lt;br&gt;
 [  3.   6.   9.  12.  15.]&lt;br&gt;
 [  4.   8.  12.  16.  20.]]&lt;/p&gt;

&lt;p&gt;A DataFrame can also be created from a dictionary whose values are arrays, but all arrays must be of the same length.&lt;/p&gt;

&lt;p&gt;d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]}&lt;br&gt;
df = DataFrame(d, index=['a', 'b', 'c', 'd'])&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;one  two&lt;br&gt;
a    1    4&lt;br&gt;
b    2    3&lt;br&gt;
c    3    2&lt;br&gt;
d    4    1&lt;/p&gt;

&lt;p&gt;When the values are not arrays, this length restriction does not apply, and any missing values will be automatically filled with NaN.&lt;/p&gt;

&lt;p&gt;d= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6, 'c': 9}]&lt;br&gt;
df = DataFrame(d)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; a  b   c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;0  1.6  2 NaN&lt;br&gt;
1  3.0  6   9&lt;/p&gt;

&lt;p&gt;When working with real-world data, you may sometimes need to create an empty DataFrame. This can be done as follows:&lt;/p&gt;

&lt;p&gt;df = DataFrame()&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Empty DataFrame&lt;br&gt;
Columns: []&lt;br&gt;
Index: []&lt;/p&gt;

&lt;p&gt;Another very useful way to create a DataFrame is by using the concat function, which allows you to build a DataFrame from one or more Series or existing DataFrames.&lt;/p&gt;

&lt;p&gt;a = Series(range(5))&lt;br&gt;
b = Series(np.linspace(4, 20, 5))&lt;br&gt;
df = pd.concat([a, b], axis=1)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;0   1&lt;br&gt;
0  0   4&lt;br&gt;
1  1   8&lt;br&gt;
2  2  12&lt;br&gt;
3  3  16&lt;br&gt;
4  4  20&lt;/p&gt;

&lt;p&gt;Here, axis=1 means concatenation by columns, while axis=0 means concatenation by rows. Note that a Series is treated as a single column, so if you choose axis=0, you’ll get a 10×1 DataFrame.&lt;/p&gt;

&lt;p&gt;The following example shows how to concatenate DataFrames by rows to form a larger DataFrame:&lt;/p&gt;

&lt;p&gt;df = DataFrame()&lt;br&gt;
index = ['alpha', 'beta', 'gamma', 'delta', 'eta']&lt;br&gt;
for i in range(5):&lt;br&gt;
    a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]])&lt;br&gt;
    df = pd.concat([df, a], axis=0)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   0  1   2   3   4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;alpha  0  0   0   0   0&lt;br&gt;
beta   1  2   3   4   5&lt;br&gt;
gamma  2  4   6   8  10&lt;br&gt;
delta  3  6   9  12  15&lt;br&gt;
eta    4  8  12  16  20&lt;/p&gt;

&lt;p&gt;3.2 Accessing Data in a DataFrame¶&lt;br&gt;
First, it’s important to emphasize again that DataFrame operations are fundamentally column-based. You can think of every operation as first selecting a column (which is a Series), and then accessing elements from that Series.&lt;/p&gt;

&lt;p&gt;You can select a column using either dataframe.column_name or dataframe[]. You’ll quickly notice that:&lt;/p&gt;

&lt;p&gt;The dot notation (dataframe.column_name) can only select a single column.&lt;/p&gt;

&lt;p&gt;The bracket notation (dataframe[]) can be used to select one or multiple columns.&lt;/p&gt;

&lt;p&gt;If the DataFrame has no column names, you can use non-negative integers (i.e., indices) inside the brackets to select columns. However, if column names do exist, then you must use those names to select columns. Also, in the absence of column names, dataframe.column_name is not valid.&lt;/p&gt;

&lt;p&gt;print(df[1])&lt;br&gt;
print(type(df[1]))&lt;br&gt;
df.columns = ['a', 'b', 'c', 'd', 'e']&lt;br&gt;
print(df['b'])&lt;br&gt;
print(type(df['b']))&lt;br&gt;
print(df.b)&lt;br&gt;
print(type(df.b))&lt;br&gt;
print(df[['a', 'd']])&lt;br&gt;
print(type(df[['a', 'd']]))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;alpha    0&lt;br&gt;
beta     2&lt;br&gt;
gamma    4&lt;br&gt;
delta    6&lt;br&gt;
eta      8&lt;br&gt;
Name: 1, dtype: float64&lt;br&gt;
&lt;br&gt;
alpha    0&lt;br&gt;
beta     2&lt;br&gt;
gamma    4&lt;br&gt;
delta    6&lt;br&gt;
eta      8&lt;br&gt;
Name: b, dtype: float64&lt;br&gt;
&lt;br&gt;
alpha    0&lt;br&gt;
beta     2&lt;br&gt;
gamma    4&lt;br&gt;
delta    6&lt;br&gt;
eta      8&lt;br&gt;
Name: b, dtype: float64&lt;br&gt;
&lt;br&gt;
       a   d&lt;br&gt;
alpha  0   0&lt;br&gt;
beta   1   4&lt;br&gt;
gamma  2   8&lt;br&gt;
delta  3  12&lt;br&gt;
eta    4  16&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;In the code above, we used dataframe.columns to assign column names to the DataFrame. As shown, when a single column is extracted, the resulting data structure is a Series. However, when two or more columns are selected, the result remains a DataFrame.&lt;/p&gt;

&lt;p&gt;To access specific elements, you can use indices or labels, just like with a Series.&lt;/p&gt;

&lt;p&gt;print df['b'][2]&lt;br&gt;
print df['b']['gamma']&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;4.0&lt;br&gt;
4.0&lt;/p&gt;

&lt;p&gt;To select rows, you can use dataframe.iloc to select by position (index number), or dataframe.loc to select by label (index name).&lt;/p&gt;

&lt;p&gt;print(df.iloc[1])&lt;br&gt;
print(df.loc['beta'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    1&lt;br&gt;
b    2&lt;br&gt;
c    3&lt;br&gt;
d    4&lt;br&gt;
e    5&lt;br&gt;
Name: beta, dtype: float64&lt;br&gt;
a    1&lt;br&gt;
b    2&lt;br&gt;
c    3&lt;br&gt;
d    4&lt;br&gt;
e    5&lt;br&gt;
Name: beta, dtype: float64&lt;/p&gt;

&lt;p&gt;Rows can also be selected using slicing or a Boolean array (Boolean mask).&lt;/p&gt;

&lt;p&gt;print("Selecting by slices:")&lt;br&gt;
print(df[1:3])&lt;br&gt;
bool_vec = [True, False, True, True, False]&lt;br&gt;
print("Selecting by boolean vector:")&lt;br&gt;
print(df[bool_vec])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Selecting by slices:&lt;br&gt;
       a  b  c  d   e&lt;br&gt;
beta   1  2  3  4   5&lt;br&gt;
gamma  2  4  6  8  10&lt;br&gt;
Selecting by boolean vector:&lt;br&gt;
       a  b  c   d   e&lt;br&gt;
alpha  0  0  0   0   0&lt;br&gt;
gamma  2  4  6   8  10&lt;br&gt;
delta  3  6  9  12  15&lt;/p&gt;

&lt;p&gt;Rows and columns can be combined to select specific data.&lt;/p&gt;

&lt;p&gt;print(df[['b', 'd']].iloc[[1, 3]])&lt;br&gt;
print(df.iloc[[1, 3]][['b', 'd']])&lt;br&gt;
print(df[['b', 'd']].loc[['beta', 'delta']])&lt;br&gt;
print(df.loc[['beta', 'delta']][['b', 'd']])&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   b   d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;beta   2   4&lt;br&gt;
delta  6  12&lt;br&gt;
       b   d&lt;br&gt;
beta   2   4&lt;br&gt;
delta  6  12&lt;br&gt;
       b   d&lt;br&gt;
beta   2   4&lt;br&gt;
delta  6  12&lt;br&gt;
       b   d&lt;br&gt;
beta   2   4&lt;br&gt;
delta  6  12&lt;/p&gt;

&lt;p&gt;If you want to access a specific element at a particular position (rather than an entire row or column), the fastest way is to use dataframe.at and dataframe.iat, which access data by label and integer position, respectively.&lt;/p&gt;

&lt;p&gt;print(df.iat[2, 3])&lt;br&gt;
print(df.at['gamma', 'd'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;8.0&lt;br&gt;
8.0&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 4</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:18:19 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-4-25gc</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-4-25gc</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_4/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_4/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 4&lt;/p&gt;

&lt;p&gt;"Widely used Python Libraries"¶&lt;br&gt;
Last time we introduced NumPy. In this article, we'll focus on another commonly used library in quantitative finance: SciPy.&lt;/p&gt;

&lt;p&gt;SciPy¶&lt;br&gt;
Overview of SciPy¶&lt;br&gt;
In the previous article, we briefly introduced NumPy. Now let’s take a look at what SciPy can do. While NumPy handles vector and matrix operations—essentially functioning like an advanced scientific calculator—SciPy builds on top of NumPy and provides a more comprehensive and advanced set of functionalities. It offers a wide array of functions for statistics, optimization, interpolation, numerical integration, signal processing, and more, covering almost all fundamental scientific computing tasks.&lt;/p&gt;

&lt;p&gt;In quantitative analysis, the most commonly used areas are statistics and optimization. Therefore, this article will focus on SciPy’s statistics and optimization modules. Other modules will be introduced in future articles when relevant.&lt;/p&gt;

&lt;p&gt;This article will involve some matrix algebra. If you find it difficult, feel free to skip Part 3 or try to understand the concepts using one-dimensional scalars instead of higher-dimensional vectors.&lt;/p&gt;

&lt;p&gt;As always, let's start by importing the necessary modules. Here, we’ll be using the statistics and optimization parts of SciPy:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
import scipy.stats as stats&lt;br&gt;
import scipy.optimize as opt&lt;br&gt;
Statistics Module¶&lt;br&gt;
Generating Random Numbers¶&lt;br&gt;
Let’s begin with generating random numbers, as this will make it easier to demonstrate other concepts later. To generate n random numbers, you can use rv_continuous.rvs(size=n) or rv_discrete.rvs(size=n).&lt;/p&gt;

&lt;p&gt;rv_continuous refers to continuous probability distributions such as:&lt;/p&gt;

&lt;p&gt;Uniform distribution: uniform&lt;/p&gt;

&lt;p&gt;Normal distribution: norm&lt;/p&gt;

&lt;p&gt;Beta distribution: beta, etc.&lt;/p&gt;

&lt;p&gt;rv_discrete refers to discrete probability distributions such as:&lt;/p&gt;

&lt;p&gt;Bernoulli distribution: bernoulli&lt;/p&gt;

&lt;p&gt;Geometric distribution: geom&lt;/p&gt;

&lt;p&gt;Poisson distribution: poisson, etc.&lt;/p&gt;

&lt;p&gt;For example, to generate:&lt;/p&gt;

&lt;p&gt;10 random numbers in the interval 0,1 from a uniform distribution, and&lt;/p&gt;

&lt;p&gt;10 random numbers from a Beta distribution with parameters α and β (denoted as Beta(α,β)):&lt;/p&gt;

&lt;p&gt;rv_unif = stats.uniform.rvs(size=10)&lt;br&gt;
print rv_unif&lt;br&gt;
rv_beta = stats.beta.rvs(size=10, a=4, b=2)&lt;br&gt;
print rv_beta&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[ 0.6419336   0.48403001  0.89548809  0.73837498  0.65744886  0.41845577&lt;br&gt;
  0.3823512   0.0985301   0.66785949  0.73163835]&lt;br&gt;
[ 0.82164685  0.69563836  0.74207073  0.94348192  0.82979411  0.87013796&lt;br&gt;
  0.78412952  0.47508183  0.29296073  0.52551156]&lt;/p&gt;

&lt;p&gt;Each random distribution function in SciPy comes with built-in default parameters—for example, the uniform distribution defaults to the range 0,1. However, when you need to modify these parameters, having to type out the full command each time can be a bit tedious.&lt;/p&gt;

&lt;p&gt;To simplify this, SciPy provides a "freezing" feature. This allows you to create a frozen distribution object with fixed parameters, so you don't need to repeatedly specify them. This is particularly useful in scenarios where you work with the same distribution settings multiple times.&lt;/p&gt;

&lt;p&gt;For example, in the case of the Beta distribution, instead of specifying the parameters α and β every time you call .rvs(), you can define a frozen distribution like this:&lt;/p&gt;

&lt;p&gt;np.random.seed(seed=2015)&lt;br&gt;
rv_beta = stats.beta.rvs(size=10, a=4, b=2)&lt;br&gt;
print "method 1:"&lt;br&gt;
print rv_beta&lt;/p&gt;

&lt;p&gt;np.random.seed(seed=2015)&lt;br&gt;
beta = stats.beta(a=4, b=2)&lt;br&gt;
print "method 2:"&lt;br&gt;
print beta.rvs(size=10)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;method 1:&lt;br&gt;
[ 0.43857338  0.9411551   0.75116671  0.92002864  0.62030521  0.56585548&lt;br&gt;
  0.41843548  0.5953096   0.88983036  0.94675351]&lt;br&gt;
method 2:&lt;br&gt;
[ 0.43857338  0.9411551   0.75116671  0.92002864  0.62030521  0.56585548&lt;br&gt;
  0.41843548  0.5953096   0.88983036  0.94675351]&lt;/p&gt;

&lt;p&gt;Hypothesis Testing¶&lt;br&gt;
Now, let’s generate a dataset and examine its related statistical properties. (You can find the parameters and documentation for the relevant distributions here: &lt;a href="http://docs.scipy.org/doc/scipy/reference/stats.html" rel="noopener noreferrer"&gt;http://docs.scipy.org/doc/scipy/reference/stats.html&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;norm_dist = stats.norm(loc=0.5, scale=2)&lt;br&gt;
n = 200&lt;br&gt;
dat = norm_dist.rvs(size=n)&lt;br&gt;
print "mean of data is: " + str(np.mean(dat))&lt;br&gt;
print "median of data is: " + str(np.median(dat))&lt;br&gt;
print "standard deviation of data is: " + str(np.std(dat))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;mean of data is: 0.383309149888&lt;br&gt;
median of data is: 0.394980561217&lt;br&gt;
standard deviation of data is: 2.00589851641&lt;/p&gt;

&lt;p&gt;Suppose this dataset represents actual observed data—such as daily returns of a stock. We can perform a basic analysis on it. One of the simplest analyses is to test whether this dataset follows a given distribution, such as the normal distribution.&lt;/p&gt;

&lt;p&gt;This is a classic one-sample hypothesis testing problem. A commonly used method for this is the Kolmogorov–Smirnov test (K-S test).&lt;/p&gt;

&lt;p&gt;In a one-sample K-S test, the null hypothesis is that the sample comes from the specified theoretical distribution.&lt;/p&gt;

&lt;p&gt;In SciPy, this can be done using the kstest function, where the parameters are:&lt;/p&gt;

&lt;p&gt;the dataset,&lt;/p&gt;

&lt;p&gt;the name of the distribution to test against (as a string),&lt;/p&gt;

&lt;p&gt;and the parameters of that distribution.&lt;/p&gt;

&lt;p&gt;mu = np.mean(dat)&lt;br&gt;
sigma = np.std(dat)&lt;br&gt;
stat_val, p_val = stats.kstest(dat, 'norm', (mu, sigma))&lt;br&gt;
print 'KS-statistic D = %6.3f p-value = %6.4f' % (stat_val, p_val)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;KS-statistic D =  0.037 p-value = 0.9428&lt;/p&gt;

&lt;p&gt;If the p-value from the hypothesis test is large (note that under the null hypothesis, the p-value is a random variable uniformly distributed over the interval 0,1; see: &lt;a href="http://en.wikipedia.org/wiki/P-value" rel="noopener noreferrer"&gt;http://en.wikipedia.org/wiki/P-value&lt;/a&gt;), then we fail to reject the null hypothesis—in other words, we accept that the data passes the normality test.&lt;/p&gt;

&lt;p&gt;Given the assumption of normality, we can further test whether the mean of this dataset is significantly different from zero. A common method for this is the t-test, specifically the one-sample t-test.&lt;/p&gt;

&lt;p&gt;In SciPy, this is done using the ttest_1samp function:&lt;/p&gt;

&lt;p&gt;stat_val, p_val = stats.ttest_1samp(dat, 0)&lt;br&gt;
print 'One-sample t-statistic D = %6.3f, p-value = %6.4f' % (stat_val, p_val)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;One-sample t-statistic D =  2.696, p-value = 0.0076&lt;/p&gt;

&lt;p&gt;We observe that p-value &amp;lt; 0.05, which means that under a significance level of 0.05, we should reject the null hypothesis—that is, the data’s mean is not equal to 0.&lt;/p&gt;

&lt;p&gt;Next, let’s generate another dataset and try a two-sample t-test using ttest_ind. This test checks whether two independent samples have significantly different means.&lt;/p&gt;

&lt;p&gt;norm_dist2 = stats.norm(loc=-0.2, scale=1.2)&lt;br&gt;
dat2 = norm_dist2.rvs(size=n/2)&lt;br&gt;
stat_val, p_val = stats.ttest_ind(dat, dat2, equal_var=False)&lt;br&gt;
print 'Two-sample t-statistic D = %6.3f, p-value = %6.4f' % (stat_val, p_val)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Two-sample t-statistic D =  3.572, p-value = 0.0004&lt;/p&gt;

&lt;p&gt;Note that in this case, the second dataset we generated differs from the first in terms of sample size and variance. Therefore, when performing the t-test, we need to use Welch’s t-test by setting equal_var=False in the ttest_ind function.&lt;/p&gt;

&lt;p&gt;We again obtain a relatively small p-value, which means that under the 0.05 significance level, we reject the null hypothesis and conclude that the two groups do not have equal means.&lt;/p&gt;

&lt;p&gt;The scipy.stats module also provides many other hypothesis testing functions, such as:&lt;/p&gt;

&lt;p&gt;bartlett and levene: for testing whether two or more samples have equal variances.&lt;/p&gt;

&lt;p&gt;anderson_ksamp: for performing the Anderson-Darling k-sample test, used to check whether multiple samples come from the same distribution.&lt;/p&gt;

&lt;p&gt;These tools are useful for more advanced statistical analysis depending on the properties of your data.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 3</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:06:50 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-3-54hf</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-3-54hf</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_3/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_3/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 3&lt;/p&gt;

&lt;p&gt;"Widely used Python Libraries"¶&lt;br&gt;
The upcoming series will introduce some of the most widely used Python libraries in quantitative finance:&lt;/p&gt;

&lt;p&gt;numpy&lt;/p&gt;

&lt;p&gt;scipy&lt;/p&gt;

&lt;p&gt;pandas&lt;/p&gt;

&lt;p&gt;matplotlib&lt;/p&gt;

&lt;p&gt;Each will be explained one by one for beginners.&lt;/p&gt;

&lt;p&gt;NumPy¶&lt;br&gt;
What is NumPy¶&lt;br&gt;
Quantitative analysis involves a large amount of numerical computation, so having an efficient and convenient scientific computing tool is essential. Python was not originally designed as a language for scientific computing. However, as more people recognized its ease of use, a wide range of external extensions emerged—NumPy (Numeric Python) being one of them.&lt;/p&gt;

&lt;p&gt;NumPy provides a wealth of tools for numerical programming, making it easy to handle operations on vectors, matrices, and more, which significantly facilitates scientific computing tasks. On the other hand, Python is free, and compared to the high costs of using software like MATLAB, NumPy has made Python an increasingly popular choice.&lt;/p&gt;

&lt;p&gt;Let’s take a quick look at how to get started with NumPy:&lt;/p&gt;

&lt;p&gt;import numpy&lt;br&gt;
numpy.version.full_version&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;2.2.4&lt;/p&gt;

&lt;p&gt;We used the import command to load the NumPy library and checked the version with numpy.version.full_version, which turned out to be 2.2.4&lt;/p&gt;

&lt;p&gt;In the upcoming lessons, we’ll frequently use functions from NumPy. However, constantly writing numpy as a prefix before every function call can be tedious. As mentioned earlier, there’s a shortcut when importing external modules: using from numpy import * allows you to access all functions without the prefix.&lt;/p&gt;

&lt;p&gt;Problem solved? Not so fast!&lt;/p&gt;

&lt;p&gt;Python has thousands of external modules, and in practice, it’s common to import several of them at once. If two modules happen to include functions or properties with the same name, this can lead to conflicts. To avoid such name clashes—also known as namespace confusion—it’s generally better to keep the module prefix.&lt;/p&gt;

&lt;p&gt;So is there a simpler way? Yes—when importing a module, you can assign it an alias. This way, you don’t need to write the full module name every time. For example, we can import NumPy as np and call version.full_version like this:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
np.version.full_version&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;2.2.4&lt;/p&gt;

&lt;p&gt;A First Look at NumPy Objects: Arrays¶&lt;br&gt;
The fundamental object in NumPy is the homogeneous multidimensional array, meaning all elements in the array must be of the same type—just like arrays in C++. For example, character and numeric types cannot coexist in the same array.&lt;/p&gt;

&lt;p&gt;Let’s look at an example:&lt;/p&gt;

&lt;p&gt;a = np.arange(20)&lt;br&gt;
Here, we’ve created a one-dimensional array a starting from 0, with a step size of 1, and a total length of 20. In Python, indexing starts at 0, so users coming from R or MATLAB should be cautious about this difference. You can use print to view the array:&lt;/p&gt;

&lt;p&gt;print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]&lt;/p&gt;

&lt;p&gt;We can use the type function to check the type of a. Here, it shows that a is an array:&lt;/p&gt;

&lt;p&gt;type(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;numpy.ndarray&lt;/p&gt;

&lt;p&gt;Using the reshape function, we can restructure this array. For example, we can create a 4×5 two-dimensional array. The arguments passed to reshape specify the size of each dimension, and the data is arranged in order by dimension (for two dimensions, this means row-wise order). This is different from R, where arrays are filled column-wise by default.&lt;/p&gt;

&lt;p&gt;a = a.reshape(4, 5)&lt;br&gt;
print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;/p&gt;

&lt;p&gt;Creating higher-dimensional arrays is no problem either:&lt;/p&gt;

&lt;p&gt;a = a.reshape(2, 2, 5)&lt;br&gt;
print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[[ 0  1  2  3  4]&lt;br&gt;
  [ 5  6  7  8  9]]&lt;/p&gt;

&lt;p&gt;[[10 11 12 13 14]&lt;br&gt;
  [15 16 17 18 19]]]&lt;/p&gt;

&lt;p&gt;Since a is an array, we can call its associated functions to further inspect its properties:&lt;/p&gt;

&lt;p&gt;ndim shows the number of dimensions&lt;/p&gt;

&lt;p&gt;shape returns the size of each dimension&lt;/p&gt;

&lt;p&gt;size gives the total number of elements (equal to the product of all dimension sizes)&lt;/p&gt;

&lt;p&gt;dtype displays the data type of the elements&lt;/p&gt;

&lt;p&gt;itemsize (not dsize) shows the number of bytes each element occupies&lt;/p&gt;

&lt;p&gt;a.ndim&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;3&lt;/p&gt;

&lt;p&gt;a.shape&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;(2, 2, 5)&lt;/p&gt;

&lt;p&gt;a.size&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;20&lt;/p&gt;

&lt;p&gt;a.dtype&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;dtype('int64')&lt;/p&gt;

&lt;p&gt;Creating Arrays¶&lt;br&gt;
Arrays can be created by converting lists, and higher-dimensional arrays can be created by converting nested lists.&lt;/p&gt;

&lt;p&gt;raw = [0,1,2,3,4]&lt;br&gt;
a = np.array(raw)&lt;br&gt;
a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([0, 1, 2, 3, 4])&lt;/p&gt;

&lt;p&gt;raw = [[0,1,2,3,4], [5,6,7,8,9]]&lt;br&gt;
b = np.array(raw)&lt;br&gt;
b&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([[0, 1, 2, 3, 4],&lt;br&gt;
       [5, 6, 7, 8, 9]])&lt;/p&gt;

&lt;p&gt;Some special arrays have dedicated commands for creation—for example, a 4×5 matrix filled with zeros:&lt;/p&gt;

&lt;p&gt;d = (4, 5)&lt;br&gt;
np.zeros(d)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([[ 0.,  0.,  0.,  0.,  0.],&lt;br&gt;
       [ 0.,  0.,  0.,  0.,  0.],&lt;br&gt;
       [ 0.,  0.,  0.,  0.,  0.],&lt;br&gt;
       [ 0.,  0.,  0.,  0.,  0.]])&lt;/p&gt;

&lt;p&gt;By default, the generated array is of float type, but you can specify the data type to create an integer array instead:&lt;/p&gt;

&lt;p&gt;d = (4, 5)&lt;br&gt;
np.ones(d, dtype=int)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([[1, 1, 1, 1, 1],&lt;br&gt;
       [1, 1, 1, 1, 1],&lt;br&gt;
       [1, 1, 1, 1, 1],&lt;br&gt;
       [1, 1, 1, 1, 1]])&lt;/p&gt;

&lt;p&gt;An array of random numbers in the interval [0,1):&lt;/p&gt;

&lt;p&gt;np.random.rand(5)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([ 0.93807818,  0.45307847,  0.90732828,  0.36099623,  0.71981451])&lt;/p&gt;

&lt;p&gt;Array Operations¶&lt;br&gt;
Basic arithmetic operations have been overloaded—operators like +, -, *, and / are all applied element-wise to the entire array. For example, with addition:&lt;/p&gt;

&lt;p&gt;a = np.array([[1.0, 2], [2, 4]])&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
b = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
print("a+b:")&lt;br&gt;
print(a+b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 1.  2.]&lt;br&gt;
 [ 2.  4.]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  1.5]&lt;br&gt;
 [ 2.5  4. ]]&lt;br&gt;
a+b:&lt;br&gt;
[[ 4.2  3.5]&lt;br&gt;
 [ 4.5  8. ]]&lt;/p&gt;

&lt;p&gt;Here, you can see that even though only one element in array a is a float and the rest are integers, Python automatically converts all elements to float—because NumPy arrays are homogeneous. Also, when adding two 2D arrays, the size of each dimension must match.&lt;/p&gt;

&lt;p&gt;Of course, in NumPy, these operators can also be used between a scalar and an array. The result is that the operation is applied element-wise between the scalar and each element in the array, and the output is still an array.&lt;/p&gt;

&lt;p&gt;print("3 * a:")&lt;br&gt;
print(3 * a)&lt;br&gt;
print("b + 1.8:")&lt;br&gt;
print(b + 1.8)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;3 * a:&lt;br&gt;
[[  3.   6.]&lt;br&gt;
 [  6.  12.]]&lt;br&gt;
b + 1.8:&lt;br&gt;
[[ 5.   3.3]&lt;br&gt;
 [ 4.3  5.8]]&lt;/p&gt;

&lt;p&gt;Just like in C++, the +=, -=, *=, and /= operators are also supported in NumPy.&lt;/p&gt;

&lt;p&gt;a /= 2&lt;br&gt;
print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 0.5  1. ]&lt;br&gt;
 [ 1.   2. ]]&lt;/p&gt;

&lt;p&gt;Taking square roots or computing exponentials is also very straightforward:&lt;/p&gt;

&lt;p&gt;print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("np.exp(a):")&lt;br&gt;
print(np.exp(a))&lt;br&gt;
print("np.sqrt(a):")&lt;br&gt;
print(np.sqrt(a))&lt;br&gt;
print("np.square(a):")&lt;br&gt;
print(np.square(a))&lt;br&gt;
print("np.power(a, 3):")&lt;br&gt;
print(np.power(a, 3))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.5  1. ]&lt;br&gt;
 [ 1.   2. ]]&lt;br&gt;
np.exp(a):&lt;br&gt;
[[ 1.64872127  2.71828183]&lt;br&gt;
 [ 2.71828183  7.3890561 ]]&lt;br&gt;
np.sqrt(a):&lt;br&gt;
[[ 0.70710678  1.        ]&lt;br&gt;
 [ 1.          1.41421356]]&lt;br&gt;
np.square(a):&lt;br&gt;
[[ 0.25  1.  ]&lt;br&gt;
 [ 1.    4.  ]]&lt;br&gt;
np.power(a, 3):&lt;br&gt;
[[ 0.125  1.   ]&lt;br&gt;
 [ 1.     8.   ]]&lt;/p&gt;

&lt;p&gt;Need to find the maximum or minimum of a 2D array? Want to calculate the total sum of all elements, or sum by rows or columns? Use a for loop? No need—NumPy’s ndarray class already provides built-in functions for these operations:&lt;/p&gt;

&lt;p&gt;a = np.arange(20).reshape(4,5)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("sum of all elements in a: " + str(a.sum()))&lt;br&gt;
print("maximum element in a: " + str(a.max()))&lt;br&gt;
print("minimum element in a: " + str(a.min()))&lt;br&gt;
print("maximum element in each row of a: " + str(a.max(axis=1)))&lt;br&gt;
print("minimum element in each column of a: " + str(a.min(axis=0)))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;br&gt;
sum of all elements in a: 190&lt;br&gt;
maximum element in a: 19&lt;br&gt;
minimum element in a: 0&lt;br&gt;
maximum element in each row of a: [ 4  9 14 19]&lt;br&gt;
minimum element in each column of a: [0 1 2 3 4]&lt;/p&gt;

&lt;p&gt;Matrix operations are heavily used in scientific computing. In addition to arrays, NumPy also provides a dedicated matrix object. There are two main differences between matrices and arrays:&lt;/p&gt;

&lt;p&gt;Matrices are strictly 2-dimensional, whereas arrays can have any number of dimensions (as long as they are positive integers).&lt;/p&gt;

&lt;p&gt;The * operator performs matrix multiplication for matrix objects, meaning the number of columns in the left matrix must equal the number of rows in the right matrix. In contrast, for arrays, the * operator performs element-wise multiplication, requiring that the arrays have the same shape.&lt;/p&gt;

&lt;p&gt;You can convert an array to a matrix using asmatrix or mat, or you can create a matrix directly. For example:&lt;/p&gt;

&lt;p&gt;a = np.arange(20).reshape(4, 5)&lt;br&gt;
a = np.asmatrix(a)&lt;br&gt;
print(type(a))&lt;/p&gt;

&lt;p&gt;b = np.matrix('1.0 2.0; 3.0 4.0')&lt;br&gt;
print(type(b))&lt;br&gt;
the output:&lt;/p&gt;



&lt;p&gt;Let’s take another look at matrix multiplication. Here, we use the arange function to generate another matrix b. The arange function can also be called with the form arange(start, stop, step) to create an arithmetic sequence. Note that the range includes the start value but excludes the stop value.&lt;/p&gt;

&lt;p&gt;b = np.arange(2, 45, 3).reshape(5, 3)&lt;br&gt;
b = np.mat(b)&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 2  5  8]&lt;br&gt;
 [11 14 17]&lt;br&gt;
 [20 23 26]&lt;br&gt;
 [29 32 35]&lt;br&gt;
 [38 41 44]]&lt;/p&gt;

&lt;p&gt;Some might ask: arange specifies the step size, but what if you want to specify the length of the generated 1D array instead? No problem — linspace can do just that.&lt;/p&gt;

&lt;p&gt;np.linspace(0, 2, 9)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])&lt;/p&gt;

&lt;p&gt;Back to our problem: perform matrix multiplication on matrices a and b.&lt;/p&gt;

&lt;p&gt;print("matrix a:")&lt;br&gt;
print(a)&lt;br&gt;
print("matrix b:")&lt;br&gt;
print(b)&lt;br&gt;
c = a * b&lt;br&gt;
print("matrix c:")&lt;br&gt;
print(c)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;matrix a:&lt;br&gt;
[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;br&gt;
matrix b:&lt;br&gt;
[[ 2  5  8]&lt;br&gt;
 [11 14 17]&lt;br&gt;
 [20 23 26]&lt;br&gt;
 [29 32 35]&lt;br&gt;
 [38 41 44]]&lt;br&gt;
matrix c:&lt;br&gt;
[[ 290  320  350]&lt;br&gt;
 [ 790  895 1000]&lt;br&gt;
 [1290 1470 1650]&lt;br&gt;
 [1790 2045 2300]]&lt;/p&gt;

&lt;p&gt;Array element access¶&lt;br&gt;
Elements of arrays and matrices can be accessed using indices. The following examples all use two-dimensional arrays (or matrices).&lt;/p&gt;

&lt;p&gt;a = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
print(a[0][1])&lt;br&gt;
print(a[0, 1])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;1.5&lt;br&gt;
1.5&lt;/p&gt;

&lt;p&gt;Array element values can be modified using index-based access.&lt;/p&gt;

&lt;p&gt;b = a&lt;br&gt;
a[0][1] = 2.0&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 3.2  2. ]&lt;br&gt;
 [ 2.5  4. ]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  2. ]&lt;br&gt;
 [ 2.5  4. ]]&lt;/p&gt;

&lt;p&gt;Now here comes the problem: you clearly modified a[0][1], so why did b[0][1] also change? This is a common pitfall in Python programming. The reason is that Python didn't actually make a true copy of a and assign it to b; instead, it made b point to the same memory address as a. To create a real copy of a for b, you can use copy.&lt;/p&gt;

&lt;p&gt;a = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
b = a.copy()&lt;br&gt;
a[0][1] = 2.0&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 3.2  2. ]&lt;br&gt;
 [ 2.5  4. ]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  1.5]&lt;br&gt;
 [ 2.5  4. ]]&lt;/p&gt;

&lt;p&gt;If you reassign a, meaning you point it to a different address, b will still remain at the original address.&lt;/p&gt;

&lt;p&gt;a = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
b = a&lt;br&gt;
a = np.array([[2, 1], [9, 3]])&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[2 1]&lt;br&gt;
 [9 3]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  1.5]&lt;br&gt;
 [ 2.5  4. ]]&lt;/p&gt;

&lt;p&gt;The colon : can be used to access all elements along a certain dimension — for example, to extract a specific column from a matrix.&lt;/p&gt;

&lt;p&gt;a = np.arange(20).reshape(4, 5)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("the 2nd and 4th column of a:")&lt;br&gt;
print(a[:,[1,3]])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;br&gt;
the 2nd and 4th column of a:&lt;br&gt;
[[ 1  3]&lt;br&gt;
 [ 6  8]&lt;br&gt;
 [11 13]&lt;br&gt;
 [16 18]]&lt;/p&gt;

&lt;p&gt;Let’s try something a bit more complex: extracting elements that meet certain conditions — a common task in data processing, usually applied to a single row or column. In the example below, we extract the third column elements (12 and 17) that correspond to the rows where the first column values are greater than 5 (i.e., 10 and 15).&lt;/p&gt;

&lt;p&gt;a[:, 2][a[:, 0] &amp;gt; 5]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([12, 17])&lt;/p&gt;

&lt;p&gt;The where function can be used to find the positions of specific values in an array.&lt;/p&gt;

&lt;p&gt;loc = numpy.where(a==11)&lt;br&gt;
print(loc)&lt;br&gt;
print(a[loc[0][0], loc[1][0]])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;(array([2]), array([1]))&lt;br&gt;
11&lt;/p&gt;

&lt;p&gt;Matrix operations¶&lt;br&gt;
Let’s continue using a matrix (or 2D array) as an example. First, let’s look at matrix transposition.&lt;/p&gt;

&lt;p&gt;a = np.random.rand(2,4)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
a = np.transpose(a)&lt;br&gt;
print("a is an array, by using transpose(a):")&lt;br&gt;
print(a)&lt;br&gt;
b = np.random.rand(2,4)&lt;br&gt;
b = np.mat(b)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
print("b is a matrix, by using b.T:")&lt;br&gt;
print(b.T)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.17571282  0.98510461  0.94864387  0.50078988]&lt;br&gt;
 [ 0.09457965  0.70251658  0.07134875  0.43780173]]&lt;br&gt;
a is an array, by using transpose(a):&lt;br&gt;
[[ 0.17571282  0.09457965]&lt;br&gt;
 [ 0.98510461  0.70251658]&lt;br&gt;
 [ 0.94864387  0.07134875]&lt;br&gt;
 [ 0.50078988  0.43780173]]&lt;br&gt;
b:&lt;br&gt;
[[ 0.09653644  0.46123468  0.50117363  0.69752578]&lt;br&gt;
 [ 0.60756723  0.44492537  0.05946373  0.4858369 ]]&lt;br&gt;
b is a matrix, by using b.T:&lt;br&gt;
[[ 0.09653644  0.60756723]&lt;br&gt;
 [ 0.46123468  0.44492537]&lt;br&gt;
 [ 0.50117363  0.05946373]&lt;br&gt;
 [ 0.69752578  0.4858369 ]]&lt;/p&gt;

&lt;p&gt;Matrix inversion&lt;/p&gt;

&lt;p&gt;import numpy.linalg as nlg&lt;br&gt;
a = np.random.rand(2,2)&lt;br&gt;
a = np.mat(a)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
ia = nlg.inv(a)&lt;br&gt;
print("inverse of a:")&lt;br&gt;
print(ia)&lt;br&gt;
print("a * inv(a)")&lt;br&gt;
print(a * ia)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.86211266  0.6885563 ]&lt;br&gt;
 [ 0.28798536  0.70810425]]&lt;br&gt;
inverse of a:&lt;br&gt;
[[ 1.71798445 -1.6705577 ]&lt;br&gt;
 [-0.69870271  2.09163573]]&lt;br&gt;
a * inv(a)&lt;br&gt;
[[ 1.  0.]&lt;br&gt;
 [ 0.  1.]]&lt;/p&gt;

&lt;p&gt;Computing eigenvalues and eigenvectors&lt;/p&gt;

&lt;p&gt;a = np.random.rand(3,3)&lt;br&gt;
eig_value, eig_vector = nlg.eig(a)&lt;br&gt;
print("eigen value:")&lt;br&gt;
print(eig_value)&lt;br&gt;
print("eigen vector:")&lt;br&gt;
print(eig_vector)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;eigen value:&lt;br&gt;
[ 1.35760609  0.43205379 -0.53470662]&lt;br&gt;
eigen vector:&lt;br&gt;
[[-0.76595379 -0.88231952 -0.07390831]&lt;br&gt;
 [-0.55170557  0.21659887 -0.74213622]&lt;br&gt;
 [-0.33005418  0.41784829  0.66616169]]&lt;/p&gt;

&lt;p&gt;Concatenate two vectors into a matrix by columns.&lt;/p&gt;

&lt;p&gt;a = np.array((1,2,3))&lt;br&gt;
b = np.array((2,3,4))&lt;br&gt;
print np.column_stack((a,b))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[1 2]&lt;br&gt;
 [2 3]&lt;br&gt;
 [3 4]]&lt;/p&gt;

&lt;p&gt;After processing some data in a loop and obtaining results, it's often useful to combine those results into a matrix. This can be done using vstack and hstack.&lt;/p&gt;

&lt;p&gt;a = np.random.rand(2,2)&lt;br&gt;
b = np.random.rand(2,2)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
c = np.hstack([a,b])&lt;br&gt;
d = np.vstack([a,b])&lt;br&gt;
print("horizontal stacking a and b:")&lt;br&gt;
print(c)&lt;br&gt;
print("vertical stacking a and b:")&lt;br&gt;
print(d)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.6738195   0.4944045 ]&lt;br&gt;
 [ 0.25702675  0.15422012]]&lt;br&gt;
b:&lt;br&gt;
[[ 0.6738195   0.4944045 ]&lt;br&gt;
 [ 0.25702675  0.15422012]]&lt;br&gt;
horizontal stacking a and b:&lt;br&gt;
[[ 0.6738195   0.4944045   0.28058267  0.0967197 ]&lt;br&gt;
 [ 0.25702675  0.15422012  0.55191041  0.04694485]]&lt;br&gt;
vertical stacking a and b:&lt;br&gt;
[[ 0.6738195   0.4944045 ]&lt;br&gt;
 [ 0.25702675  0.15422012]&lt;br&gt;
 [ 0.28058267  0.0967197 ]&lt;br&gt;
 [ 0.55191041  0.04694485]]&lt;/p&gt;

&lt;p&gt;Missing Value¶&lt;br&gt;
Missing values are also a form of information in data analysis. NumPy provides nan to represent missing values, and isnan can be used to detect them.&lt;/p&gt;

&lt;p&gt;a = np.random.rand(2,2)&lt;br&gt;
a[0, 1] = np.nan&lt;br&gt;
print(np.isnan(a))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[False  True]&lt;br&gt;
 [False False]]&lt;/p&gt;

&lt;p&gt;nan_to_num can be used to replace nan with 0. In the more advanced module pandas, which we’ll cover later, we’ll see that it provides functions that allow you to specify the replacement value for nan.&lt;/p&gt;

&lt;p&gt;print(np.nan_to_num(a))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 0.58144238  0.        ]&lt;br&gt;
 [ 0.26789784  0.48664306]]&lt;/p&gt;

&lt;p&gt;NumPy offers many more functions. For a detailed understanding, you can refer to the following links: &lt;a href="http://wiki.scipy.org/Numpy_Example_List" rel="noopener noreferrer"&gt;http://wiki.scipy.org/Numpy_Example_List&lt;/a&gt; and &lt;a href="http://docs.scipy.org/doc/numpy" rel="noopener noreferrer"&gt;http://docs.scipy.org/doc/numpy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 2</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:04:53 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-2-57m4</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-2-57m4</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_2/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_2/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 2&lt;/p&gt;

&lt;p&gt;"Who will teach me about Python?"¶&lt;br&gt;
On the first day, We learned the basic operations of Python and several main container types.&lt;/p&gt;

&lt;p&gt;Today, We will learn Python's functions, loops and conditionals, and classes. With this, We will have a general understanding of Python. The learning outline for today is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Functions¶&lt;br&gt;
a) Defining a function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loops and Conditionals¶&lt;br&gt;
a) if statements&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;b) while True / break statements&lt;/p&gt;

&lt;p&gt;c) for loops&lt;/p&gt;

&lt;p&gt;d) List comprehensions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Classes¶
a) A casual talk about classes and objects&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;b) Defining a class&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Functions¶
a) Defining a function¶
(1) Definition Rules&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When introducing list methods, we already briefly mentioned functions. Anyone who has studied mathematics knows what a function is — it takes an input (a parameter) and returns a value. Functions can also be defined by yourself, using the following format:&lt;/p&gt;

&lt;p&gt;def function_name(parameter):&lt;br&gt;
    # function code&lt;br&gt;
In the function code, return indicates the value to be returned. For example, to define a square function square(x) that takes x as input and returns the square of x:&lt;/p&gt;

&lt;p&gt;def square(x):return x*x&lt;/p&gt;

&lt;p&gt;square(9)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;81&lt;/p&gt;

&lt;p&gt;(2) Defining Functions with Variable Parameters&lt;/p&gt;

&lt;p&gt;Sometimes you need to define a function with a variable number of parameters. There are several ways to do this:&lt;/p&gt;

&lt;p&gt;Assign default values to parameters For example, define a function like f(a, b=1, c='hehe'). In this case, the last two parameters are optional — if not specified during the function call, they will default to b=1 and c='hehe'. Therefore, the following calls are all valid:&lt;/p&gt;

&lt;p&gt;f('dsds')&lt;br&gt;
f('dsds', 2)&lt;br&gt;
f('dsds', 2, 'hdasda')&lt;br&gt;
Keyword arguments The method above fixes the order of parameters — the first value is assigned to the first parameter. With keyword arguments, however, you can specify which value goes to which parameter by name. For example, still using the function f(a, b=1, c='hehe'), you can call it like this:&lt;/p&gt;

&lt;p&gt;f(b=2, a=11)&lt;br&gt;
The order of parameters can be changed as long as you specify them using their keywords.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Loops and Conditionals¶
Note that Python uses indentation to indicate which block of code belongs to the loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;a) if statements¶&lt;br&gt;
Also note two things: first, indentation; and second, a colon (:) is required after the condition.&lt;/p&gt;

&lt;p&gt;j=2.67&lt;br&gt;
if j&amp;lt;3:&lt;br&gt;
    print('j&amp;lt;3')&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;j&amp;lt;3&lt;/p&gt;

&lt;p&gt;For multiple conditions, note that elseif should be written as elif. The standard format is:&lt;/p&gt;

&lt;p&gt;if condition1:&lt;br&gt;
    statement1&lt;br&gt;
elif condition2:&lt;br&gt;
    statement2&lt;br&gt;
else:&lt;br&gt;
    statement3&lt;br&gt;
Note that if, elif, and else are at the same indentation level — there should be no indentation before them.&lt;/p&gt;

&lt;p&gt;t=3&lt;br&gt;
if t&amp;lt;3:&lt;br&gt;
    print('t&amp;lt;3')&lt;br&gt;
elif t==3:&lt;br&gt;
    print('t=3')&lt;br&gt;
else:&lt;br&gt;
    print('t&amp;gt;3')&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;t=3&lt;/p&gt;

&lt;p&gt;b) while True / break statements¶&lt;br&gt;
The format of this statement is:&lt;/p&gt;

&lt;p&gt;while True:  # condition is true&lt;br&gt;
    statement&lt;br&gt;
    if break_condition:&lt;br&gt;
        break&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;p&gt;a=3&lt;br&gt;
while a&amp;lt;10:&lt;br&gt;
    a=a+1&lt;br&gt;
    print(a)&lt;br&gt;
    if a==8: break&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;4&lt;br&gt;
5&lt;br&gt;
6&lt;br&gt;
7&lt;br&gt;
8&lt;/p&gt;

&lt;p&gt;Although the condition after while is a &amp;lt; 10, meaning the loop will continue as long as a is less than 10, the if condition specifies that the loop should break when a equals 8. Therefore, the output will only go up to 8.&lt;/p&gt;

&lt;p&gt;c) for loops¶&lt;br&gt;
No more explanation needed — you can iterate over a sequence, dictionary, etc.&lt;/p&gt;

&lt;p&gt;a=[1,2,3,4,5]&lt;br&gt;
for i in a:&lt;br&gt;
    print(i)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;1&lt;br&gt;
2&lt;br&gt;
3&lt;br&gt;
4&lt;br&gt;
5&lt;/p&gt;

&lt;p&gt;d) List comprehensions¶&lt;br&gt;
List comprehensions are a way to create a new list from an existing one, working similarly to a for loop. The format is:&lt;/p&gt;

&lt;p&gt;[output_value for condition]&lt;br&gt;
When the condition is met, an output value is generated, and the final result is a list.&lt;/p&gt;

&lt;p&gt;[x*x for x in range(10)]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;/p&gt;

&lt;p&gt;[x*x for x in range(10) if x%3==0]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[0, 9, 36, 81]&lt;/p&gt;

&lt;p&gt;The above example uses the sequence [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] to generate a new sequence.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Classes¶
a) A casual talk about classes and objects¶
A class is an abstract concept — it doesn't exist in the physical world in terms of time or space. A class simply defines the abstract attributes and behaviors for all its objects. For example, the class "Person" can represent many individuals, but the class itself doesn't exist as a tangible entity in the real world.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An object, on the other hand, is a concrete instance of a class. It is something that actually exists. If "Person" is an abstract class, then you, yourself, are a specific object of that class.&lt;/p&gt;

&lt;p&gt;An object of a class is also called an instance of the class. To give another analogy, a class is like a mold, and objects are the concrete things produced using that mold — each with the same attributes and methods. As the saying goes, "They look just alike, as if made from the same mold" — that’s exactly the idea here.&lt;/p&gt;

&lt;p&gt;The process of using a mold to create a concrete thing is called instantiation of the class. Let’s take a look at a specific class example below:&lt;/p&gt;

&lt;p&gt;b) Defining a class¶&lt;br&gt;
class boy:&lt;br&gt;
    gender='male'&lt;br&gt;
    interest='girl'&lt;br&gt;
    def say(self):&lt;br&gt;
        return 'i am a boy'&lt;br&gt;
The statement above defines a class called boy. Now let’s use this class model to construct a specific object:&lt;/p&gt;

&lt;p&gt;peter=boy()&lt;br&gt;
Now let’s take a look at the attributes and methods of the specific instance peter.&lt;/p&gt;

&lt;p&gt;“What are attributes and methods?”&lt;/p&gt;

&lt;p&gt;They are two forms of a class:&lt;/p&gt;

&lt;p&gt;Attributes are the static aspects&lt;/p&gt;

&lt;p&gt;Methods are the dynamic aspects&lt;/p&gt;

&lt;p&gt;For example, the class “Person” may have attributes such as name, gender, height, age, and weight. It may also have methods such as walking, running, and jumping.&lt;/p&gt;

&lt;p&gt;peter.gender&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'male'&lt;/p&gt;

&lt;p&gt;peter.interest&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'girl'&lt;/p&gt;

&lt;p&gt;peter.say()&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'i am a boy'&lt;/p&gt;

&lt;p&gt;Here, gender and interest are attributes of peter, while say is his method. If we instantiate another object, for example sam:&lt;/p&gt;

&lt;p&gt;sam=boy()&lt;br&gt;
Then sam and peter have the same attributes and methods — you could say, “They were truly made from the same mold!”&lt;/p&gt;

&lt;p&gt;Learning more fromhttps://godzilla.dev/&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 1</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Fri, 03 Jul 2026 07:45:50 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-1-h5e</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-1-h5e</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_1/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_1/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Why I should learn Python even if Cursor do everything for me?”&lt;br&gt;
True. you can ask Cursor to generate python code for you now in 2025. but still the ability to read and run the code is important&lt;/p&gt;

&lt;p&gt;These series help you to be an expert to work with AI to trade&lt;/p&gt;

&lt;p&gt;“Who will teach me about Python?”&lt;br&gt;
As a complete beginner with no background, I just want to get a rough idea of Python, write some simple programs, and be able to understand common code. I don’t know anything about Java, C, inheritance, exceptions, and so on. So, I looked up a lot of information and wrote the following diary entry, hoping to understand Python — an increasingly important language in the field of quantitative trading — from the perspective of an absolute beginner.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Learning the basic
Before formally introducing Python, it’s beneficial to understand the following two basic operations for later learning:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;a) Basic Input and Output&lt;br&gt;
You can use +, -, *, / to perform basic arithmetic operations directly in Python.&lt;/p&gt;

&lt;p&gt;1+3*3&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;10&lt;br&gt;
b) Importing Modules&lt;br&gt;
You can import modules using the import statement. Once imported, you can use the functions within that module.&lt;/p&gt;

&lt;p&gt;For example, you can import the math module and then use the sqrt function from the math module.&lt;/p&gt;

&lt;p&gt;import math&lt;br&gt;
math.sqrt(9)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;3.0&lt;br&gt;
At this point, I had a question:&lt;/p&gt;

&lt;p&gt;“Do I have to include the ‘math’ module prefix every time I reference a function? Can I use it without the prefix?”&lt;/p&gt;

&lt;p&gt;Directly typing sqrt(9) will result in an error, which is quite annoying. So, is there a way to use the function without always including the prefix? Yes, there is a way — you can use the format from module import function to “extract” the function directly.&lt;/p&gt;

&lt;p&gt;from math import sqrt&lt;br&gt;
sqrt(9)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;3.0&lt;br&gt;
This way, I don’t need to add the ‘math’ prefix every time I use the sqrt function. Just as I was about to move on, another question arose:&lt;/p&gt;

&lt;p&gt;“With so many functions under the math module, is there a way to write one statement and then use all functions from math directly?”&lt;/p&gt;

&lt;p&gt;After using the sqrt function from the math module with a from…import…, and then I need to use floor, I would have to write another import. This is also quite bothersome. However, there is a way to “extract” all functions at once:&lt;/p&gt;

&lt;p&gt;from math import *&lt;br&gt;
print sqrt(9)&lt;br&gt;
print floor(32.9)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;3.0&lt;br&gt;
32.0&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Containers
a) What are Containers
When starting to learn Python, I was quite confused by its data structures, such as dictionaries, sequences, tuples, etc. I suspect there are other beginners who feel the same, so I organized some information for retention:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, let’s start with containers. In Python, there is a type of data structure known as containers. As the name implies, a container is a vessel for storing data. It mainly includes sequences and dictionaries, where sequences mainly comprise lists, tuples, strings, etc. (see the diagram below).&lt;/p&gt;

&lt;p&gt;The basic form of a list, for example: [1, 3, 6, 10] or [‘yes’, ‘no’, ‘OK’]&lt;/p&gt;

&lt;p&gt;The basic form of a tuple, for example: (1, 3, 6, 10) or (‘yes’, ‘no’, ‘OK’)&lt;/p&gt;

&lt;p&gt;The basic form of a string, for example: ‘hello’&lt;/p&gt;

&lt;p&gt;The above are all types of sequences. Each element in a sequence is assigned a number — its position, also known as an “index.” The index of the first element is 0, the second is 1, and so on. The main difference between lists and tuples is that lists can be modified, while tuples cannot (note that lists use square brackets while tuples use parentheses). This characteristic of sequences allows us to access specific elements in a sequence using indices, for example:&lt;/p&gt;

&lt;p&gt;a=[1,3,6,10]&lt;br&gt;
a[2]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;6&lt;br&gt;
b=(1,3,6,10)&lt;br&gt;
b[2]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;6&lt;br&gt;
c='hello'&lt;br&gt;
c[0:3]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'hel'&lt;br&gt;
In contrast to sequences, the “dictionary” is a different type of container — it is unordered.&lt;/p&gt;

&lt;p&gt;Its basic form, for example, is: d = {7: ‘seven’, 8: ‘eight’, 9: ‘nine’}&lt;/p&gt;

&lt;p&gt;This is a “key-value” mapping structure. Therefore, elements in a dictionary cannot be accessed through indices like in sequences, but rather by using the keys to access the elements:&lt;/p&gt;

&lt;p&gt;d={7:'seven',8:'eight',9:'nine'}&lt;br&gt;
d[8]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'eight'&lt;br&gt;
b) Some Common Operations on Sequences&lt;br&gt;
In addition to the indexing mentioned above, lists, tuples, strings, and other sequences share some common operations.&lt;/p&gt;

&lt;p&gt;(1) Indexing (supplementing the above)&lt;/p&gt;

&lt;p&gt;The index of the last element in a sequence can also be -1, the second to last can be -2, and so forth:&lt;/p&gt;

&lt;p&gt;a=[1,3,6,10]&lt;br&gt;
print a[3]&lt;br&gt;
print a[-1]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;10&lt;br&gt;
10&lt;br&gt;
(2) Slicing&lt;/p&gt;

&lt;p&gt;Use slicing to access elements within a specific range. The format for slicing is:&lt;/p&gt;

&lt;p&gt;a[start_index:end_index:step]&lt;/p&gt;

&lt;p&gt;This accesses elements starting from the element at the start index up to, but not including, the element at the end index, visiting every ‘step’ elements along the way. The step can be omitted, in which case the default step is 1.&lt;/p&gt;

&lt;p&gt;c='hello'&lt;br&gt;
c[0:3]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'hel'&lt;br&gt;
This is like dividing a sequence into several slices, which is why it’s called “slicing.”&lt;/p&gt;

&lt;p&gt;(3) Sequence Concatenation&lt;/p&gt;

&lt;p&gt;This involves merging two sequences together. Only sequences of the same type can be concatenated.&lt;/p&gt;

&lt;p&gt;[1,2,3]+[4,5,6]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[1, 2, 3, 4, 5, 6]&lt;br&gt;
'hello,'+'world!'&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'hello,world!'&lt;br&gt;
(4) Membership&lt;/p&gt;

&lt;p&gt;To check if a value is in a sequence, you can use the in operator.&lt;/p&gt;

&lt;p&gt;a='hello'&lt;br&gt;
print 'o' in a&lt;br&gt;
print 't' in a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;True&lt;br&gt;
False&lt;br&gt;
c) List Operations&lt;br&gt;
The above are some operations common to all sequences, but lists also have some unique operations that other sequences do not have.&lt;/p&gt;

&lt;p&gt;(1) List Function&lt;/p&gt;

&lt;p&gt;You can convert a sequence into a list using the list(sequence) function.&lt;/p&gt;

&lt;p&gt;list('hello')&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to2"&gt;'h', 'e', 'l', 'l', 'o'&lt;/a&gt; Element Assignment and Deletion&lt;/p&gt;

&lt;p&gt;Element Deletion — del a[index]&lt;/p&gt;

&lt;p&gt;Element Assignment — a[index] = value&lt;/p&gt;

&lt;p&gt;a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'hello'&lt;br&gt;
b=list(a)&lt;br&gt;
b&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 'l', 'l', 'o']&lt;br&gt;
del b[2]&lt;br&gt;
b&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 'l', 'o']&lt;br&gt;
b[2]='t'&lt;br&gt;
b&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 't', 'o']&lt;br&gt;
Slice Assignment — a[start_index:end_index] = list(value)&lt;/p&gt;

&lt;p&gt;This assigns values to elements within a specific range of the list, from the start index up to but not including the end index. For example, using the above statement, how would you change ‘hello’ to ‘heyyo’?&lt;/p&gt;

&lt;p&gt;b=list('hello')&lt;br&gt;
b&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 'l', 'l', 'o']&lt;br&gt;
b[2:4]=list('yy')&lt;br&gt;
b&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 'y', 'y', 'o']&lt;br&gt;
Note that although “ll” is at positions index 2 and 3 in the word “hello”, when assigning values, you use b[2:4] instead of b[2:3]. Also, remember that list() uses parentheses.&lt;/p&gt;

&lt;p&gt;(3) List Methods&lt;/p&gt;

&lt;p&gt;As mentioned above, the list function is something found in many languages, like the IF function and VLOOKUP function in Excel, the COUNT function in SQL, and the sqrt function common to various languages, among many others. Python also has many such functions. In Python, a method is a function that is “closely associated with certain objects.” Therefore, list methods are functions that belong to lists and can perform some deeper operations on them. Methods are called in this format:&lt;/p&gt;

&lt;p&gt;object.method(arguments)&lt;/p&gt;

&lt;p&gt;Thus, the call for list methods naturally follows this pattern:&lt;/p&gt;

&lt;p&gt;list.method(arguments)&lt;/p&gt;

&lt;p&gt;Here are some commonly used list methods, using a = [‘h’, ‘e’, ‘l’, ‘l’, ‘o’] as an example:&lt;/p&gt;

&lt;p&gt;a=['h','e','l','l','o']&lt;br&gt;
a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 'l', 'l', 'o']&lt;br&gt;
Insert an element m at index n of list a: a.insert(n, m)&lt;/p&gt;

&lt;p&gt;a.insert(2,'t')&lt;br&gt;
a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 't', 'l', 'l', 'o']&lt;br&gt;
Add element m to the end of the list a: a.append(m)&lt;/p&gt;

&lt;p&gt;a.append('q')&lt;br&gt;
a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'e', 't', 'l', 'l', 'o', 'q']&lt;br&gt;
Return the index of the first occurrence of element m in list a: a.index(m)&lt;/p&gt;

&lt;p&gt;a.index('e')&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;1&lt;br&gt;
Remove the first occurrence of element m from list a: a.remove(m)&lt;/p&gt;

&lt;p&gt;a.remove('e')&lt;br&gt;
a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 't', 'l', 'l', 'o', 'q']&lt;br&gt;
Sort list a in descending order: a.sort(reverse=True)&lt;/p&gt;

&lt;p&gt;a.sort()&lt;br&gt;
a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;['h', 'l', 'l', 'o', 'q', 't']&lt;br&gt;
d) Dictionary Operations&lt;br&gt;
(1) dict Function&lt;/p&gt;

&lt;p&gt;The dict function can create a dictionary using keyword arguments, with the format:&lt;/p&gt;

&lt;p&gt;dict(key1=value1, key2=value2, …) → {key1: value1, key2: value2, …}&lt;/p&gt;

&lt;p&gt;For example, how do you create a dictionary with the name name set to “jiayounet” and age age set to 28?&lt;/p&gt;

&lt;p&gt;dict(name='jiayounet',age=27)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;{'age': 27, 'name': 'jiayounet'}&lt;br&gt;
(2) Basic Operations&lt;/p&gt;

&lt;p&gt;In many ways, the basic behavior of dictionaries is similar to that of lists. The following examples use the sequence a = [1, 3, 6, 10] and the dictionary f = {‘age’: 27, ‘name’: ‘shushuo’}.&lt;/p&gt;

&lt;p&gt;Diary Summary:&lt;/p&gt;

&lt;p&gt;Today, We learned about Python’s basic interface, operations, and several main container types. Next, We need to study Python’s functions, loops and conditionals, and classes — only then We will have a general understanding of Python.&lt;/p&gt;

&lt;p&gt;Learning more from &lt;a href="https://godzilla.dev/" rel="noopener noreferrer"&gt;https://godzilla.dev/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>hft</category>
    </item>
  </channel>
</rss>
