Skip to content

Commit abfc572

Browse files
committed
Add filtering of facts with no dimensions
1 parent 14d1b32 commit abfc572

3 files changed

Lines changed: 46 additions & 6 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ data/.DS_Store
1414
**/**/.DS_Store
1515
**/**/**/.DS_Store
1616
CLAUDE.md
17-
internal/*
17+
internal/*
18+
gists/bugs/*

edgar/xbrl/facts.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,21 @@ def by_date_range(self, start_date: Optional[str] = None,
242242
parse_date(f['period_end']) <= end_obj))
243243
return self
244244

245-
def by_dimension(self, dimension: str, value: Optional[str] = None) -> FactQuery:
245+
def by_dimension(self, dimension: Optional[str], value: Optional[str] = None) -> FactQuery:
246246
"""
247247
Filter facts by dimension.
248248
249249
Args:
250-
dimension: Dimension name
250+
dimension: Dimension name, or None to filter for facts with no dimensions
251251
value: Optional dimension value to filter by
252252
253253
Returns:
254254
Self for method chaining
255255
"""
256-
if value:
256+
if dimension is None:
257+
# Filter for facts with no dimensions
258+
self._filters.append(lambda f: not any(key.startswith('dim_') for key in f.keys()))
259+
elif value:
257260
self._filters.append(lambda f: f'dim_{dimension}' in f and f[f'dim_{dimension}'] == value)
258261
else:
259262
self._filters.append(lambda f: f'dim_{dimension}' in f)
@@ -585,10 +588,17 @@ def to_dataframe(self, *columns) -> pd.DataFrame:
585588
# skip these columns
586589
skip_columns = ['fact_key', 'original_label', 'period_key']
587590

591+
if 'statement_role' in df.columns:
592+
# Change the statement_role to statement name
593+
df['statement_name'] = df.statement_role.fillna('').apply(lambda s: s.split('/')[-1] if s else None)
594+
# Remove statement_role column if it exists
595+
if 'statement_role' in df.columns:
596+
df = df.drop(columns=['statement_role'])
597+
588598
# order columns
589599
first_columns = [col for col in
590600
['concept', 'label', 'value', 'numeric_value', 'period_start', 'period_end', 'period_instant',
591-
'decimals', 'statement_type', 'statement_role']
601+
'decimals', 'statement_type', 'statement_name']
592602
if col in df.columns]
593603
columns = first_columns + [col for col in df.columns
594604
if col not in first_columns

tests/test_xbrl_facts.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
from edgar.xbrl import XBRL, FactsView
77
from edgar.xbrl.facts import FactQuery
88
from rich import print
9+
import pandas as pd
910

11+
pd.options.display.max_rows = 1000
1012

1113

1214
@pytest.fixture(scope='module')
@@ -257,4 +259,31 @@ def test_facts_to_dataframe_has_correct_columns(aapl_xbrl):
257259
df = revenue_query.to_dataframe()
258260
columns = df.columns.tolist()
259261
# Assert that the columns are unique and not duplicated
260-
assert len(columns) == len(set(columns)), "Columns are duplicated in the DataFrame"
262+
assert len(columns) == len(set(columns)), "Columns are duplicated in the DataFrame"
263+
264+
265+
def test_query_by_dimension(aapl_xbrl):
266+
# Test querying by dimension
267+
facts = (aapl_xbrl
268+
.query()
269+
.by_text("Revenue")
270+
.by_dimension(dimension='us-gaap_StatementBusinessSegmentsAxis', value='aapl:AmericasSegmentMember')
271+
)
272+
df = facts.to_dataframe('concept', 'label', 'value', 'dim_us-gaap_StatementBusinessSegmentsAxis')
273+
print(df)
274+
assert len(df) == 3
275+
276+
def test_query_by_dimension_none(aapl_xbrl):
277+
# Test querying by dimension
278+
facts = (aapl_xbrl
279+
.query()
280+
.by_text("Revenue")
281+
)
282+
assert any('dim' in col for col in facts.to_dataframe().columns)
283+
facts = (aapl_xbrl
284+
.query()
285+
.by_text("Revenue")
286+
.by_dimension(None)
287+
)
288+
print(facts.to_dataframe().columns.tolist())
289+
assert not any('dim' in col for col in facts.to_dataframe().columns)

0 commit comments

Comments
 (0)