How to Group Meteorite Classes into Stony, Iron and Stony-Iron
On this page
Problem statement
The recclass column of NASA's Meteorite Landings table holds 466 different labels: L6, H5, CM2, "Iron, IIIAB", Eucrite-pmict, Martian (shergottite), Pallasite, and hundreds more used a handful of times. A chart with 466 categories says nothing, and the labels follow a scientific scheme rather than a tidy hierarchy: a letter for the chemical group, a digit for how much the rock was heated, and words for everything that fits no scheme. This page maps every label to a few groups a reader can follow, checks what the rules catch wrongly, and compares the groups' shares among falls, finds and mass.
Quick answer
Test the label's prefix in order, from the most specific names to the single letters:
def group(c):
if pd.isna(c): return "unknown"
if c.startswith("Iron"): return "iron"
if c.startswith(("Pallasite", "Mesosiderite")): return "stony-iron"
if c.startswith(("Martian", "Lunar")): return "Mars and Moon"
if c.startswith(("Eucrite", "Diogenite", "Howardite", "Ureilite", "Aubrite", "Angrite", "Acapulcoite", "Lodranite", "Winonaite", "Brachinite", "Achondrite")): return "achondrite"
if c.startswith("Chondrite"): return "other chondrite"
if c.startswith(("H", "L", "OC")): return "ordinary chondrite"
if c.startswith("C"): return "carbonaceous chondrite"
if c.startswith(("E", "R", "K")): return "other chondrite"
return "unknown"
met["group"] = met.recclass.map(group)
print(met.group.value_counts().to_string())
group
ordinary chondrite 39843
achondrite 1831
carbonaceous chondrite 1584
iron 1069
other chondrite 761
Mars and Moon 284
stony-iron 281
unknown 63
Ordinary chondrites are 39,843 of the 45,716 meteorites, nearly nine in ten. Achondrites, rocks melted on their parent asteroid, are 1,831, carbonaceous chondrites 1,584 and irons 1,069. 284 come from Mars or the Moon and 281 are stony-irons. The order of the tests matters: "Howardite" starts with H and "Lunar" with L, so the named classes have to be tested before the single letters, and "Chondrite-ung" starts with C.
What the labels encode
1. 466 labels
print(f"distinct recclass values: {met.recclass.nunique()}; used once: {(met.recclass.value_counts() == 1).sum()}")
print(met.recclass.value_counts().head(8).to_string())
distinct recclass values: 466; used once: 145
recclass
L6 8285
H5 7142
L5 4796
H6 4528
H4 4211
LL5 2766
LL6 2043
L4 1253
145 of the 466 labels are used by one meteorite only. The eight most common are all ordinary chondrites, L6 with 8,285 and H5 with 7,142 first. H, L and LL say how much iron the rock holds, high, low and low-iron low-metal, and the digit from 3 to 7 how strongly it was heated inside its asteroid.
2. What the prefix rules catch wrongly
for g_ in ["ordinary chondrite", "other chondrite", "unknown"]:
print(g_, met.loc[met.group == g_, "recclass"].value_counts().head(6).to_dict())
ordinary chondrite {'L6': 8285, 'H5': 7142, 'L5': 4796, 'H6': 4528, 'H4': 4211, 'LL5': 2766}
other chondrite {'E3': 206, 'EH3': 120, 'EL6': 72, 'Relict OC': 65, 'R4': 42, 'R5': 20}
unknown {'Stone-uncl': 50, 'Unknown': 7, 'Fusion crust': 4, 'Impact melt breccia': 1, 'Stone-ung': 1}
Look at what lands in each group, not only the counts. The ordinary chondrite group holds what it should. "Other chondrite" collects the enstatite chondrites (E3, EH3, EL6), the R chondrites, and 65 "Relict OC", ordinary chondrites so weathered that only their chromite grains survive; keep them out of an ordinary-chondrite count if you are comparing chemistry. "Unknown" is 50 "Stone-uncl", stones never classified, and a few labels such as "Fusion crust", which describe a fragment rather than a meteorite type.
3. Ordinary chondrites by type
oc = met[met.group == "ordinary chondrite"]
chem = oc.recclass.str.extract(r"^(LL|L|H)")[0]
petro = oc.recclass.str.extract(r"^(?:LL|L|H)(\d)")[0]
print(pd.crosstab(chem.rename("chemical group"), petro.rename("petrologic type")).to_string())
petrologic type 3 4 5 6 7
chemical group
H 839 4782 7427 4534 12
L 841 1375 4971 8359 21
LL 319 318 2855 2053 23
Split into chemical group and petrologic type, the ordinary chondrites show their structure. H chondrites peak at type 5, with 7,427, and L chondrites at type 6, with 8,359. Type 3, the least heated and most prized by researchers, is 839 H and 841 L. The extraction misses labels such as "H/L3" and "OC", which are left out of the table rather than forced into a cell.
Groups among falls, finds and mass
The data used on this page
NASA's Meteorite Landings table from The Meteoritical Society's records (last updated May 2013), saved on this site on 28 October 2026. The class names follow the Society's scheme as recorded in the table; the groups are this page's own.
from pathlib import Path
import json
import zipfile
import geopandas as gpd
import numpy as np
import pandas as pd
import requests
Path("data").mkdir(exist_ok=True)
# NASA's Meteorite Landings table (The Meteoritical Society's records as NASA last updated them, May 2013), every
# fireball in NASA/JPL's Fireball Data API, and Natural Earth's countries and land. Saved 28 October 2026.
# Live: https://data.nasa.gov/docs/legacy/meteorite_landings/Meteorite_Landings.csv
# https://ssd-api.jpl.nasa.gov/fireball.api?vel-comp=true
ARCHIVE = "nasa-meteorites-2026-10-28.zip"
if not Path(f"data/{ARCHIVE}").exists():
Path(f"data/{ARCHIVE}").write_bytes(requests.get(f"https://data.spatialworkflow.io/{ARCHIVE}", timeout=600).content)
Z = zipfile.ZipFile(f"data/{ARCHIVE}")
met = pd.read_csv(Z.open("Meteorite_Landings.csv")).rename(columns={"mass (g)": "mass_g"})
for f in ["ne_110m_admin_0_countries.zip", "ne_50m_land.zip"]:
Path(f"data/{f}").write_bytes(Z.read(f))
print(f"Meteorite Landings: {len(met):,} meteorites")
Meteorite Landings: 45,716 meteorites
Example 1: groups among falls and finds
print(pd.crosstab(met.group, met.fall, normalize="columns").mul(100).round(1).to_string())
fall Fell Found
group
Mars and Moon 0.5 0.6
achondrite 7.3 3.9
carbonaceous chondrite 4.0 3.5
iron 4.4 2.3
ordinary chondrite 77.3 87.4
other chondrite 1.7 1.7
stony-iron 1.0 0.6
unknown 3.8 0.0
As a share of witnessed falls, irons are 4.4% and achondrites 7.3%, against 2.3% and 3.9% of finds. Finds are dominated by ordinary chondrites, 87.4%, because the ice and desert harvests collect thousands of small chondrite stones. 3.8% of falls are "unknown", almost all "Stone-uncl": stones that fell long ago, most of them before 1900, and were never classified. A find is classified before it enters the table, so the group is empty for finds.
Example 2: groups by mass
t = met.groupby("group").mass_g.agg(["median", "sum"])
t["share of mass"] = (t["sum"] / t["sum"].sum()).map(lambda v: f"{v:.1%}")
print(t.drop(columns="sum").sort_values("median", ascending=False).round(1).to_string())
median share of mass
group
iron 10000.0 85.0%
unknown 1257.5 0.1%
stony-iron 496.2 3.4%
Mars and Moon 94.9 0.0%
achondrite 88.3 1.0%
ordinary chondrite 28.7 9.8%
carbonaceous chondrite 25.2 0.6%
other chondrite 17.9 0.2%
By mass the picture turns over. Irons are 2.3% of meteorites but 85.0% of all the recorded mass, and the median iron weighs 10 kg against 28.7 g for an ordinary chondrite. Iron survives the fall through the atmosphere in large pieces and survives weathering on the ground, so the heavy end of the record is almost all iron. A count of meteorites and a weight of meteorites answer different questions.
Internal links
- The largest meteorites β where the iron mass sits
- Falls and finds explained β why irons are over-represented among chance finds
- Reading the table β the other columns