AnkiDataFrame#

The class AnkiDataFrame is the central data structure in which we provide the notes, cards and review tables. Access it via an instance of Collection.

Example:

from ankipandas import Collection
col = Collection()

col.notes  # Notes as AnkiDataFrame
col.cards  # Cards as AnkiDataFrame
col.revs   # Reviews as AnkiDataFrame
class ankipandas.ankidf.AnkiDataFrame(*args, **kwargs)[source]#

Bases: DataFrame

__init__(*args, **kwargs)[source]#

Initializes a blank AnkiDataFrame.

Warning

It is recommended to directly initialize this class with the notes, cards or revs table, using one of the methods notes(), cards() or revs() of the Collection class instead!

Parameters:
  • *args – Internal use only. See arguments of pandas.DataFrame.

  • **kwargs – Internal use only. See arguments of pandas.DataFrame.

fields_as_columns_prefix#

Prefix for fields as columns. Default is nfld_.

classmethod init_with_table(col, table, empty=False)[source]#
check_table_integrity()[source]#
property db: Connection#

Opened Anki database (sqlite3.Connection). Make sure to call db.close() after you’re done. Better still, use contextlib.closing.

property id#

Return note/card/review ID as pandas.Series of integers.

property nid#

Note ID as pandas.Series of integers.

property cid#

Card ID as pandas.Series of integers.

property rid#

Review ID as pandas.Series of integers.

property mid#

Model ID as pandas.Series of integers.

property did#

Deck ID as pandas.Series of integers.

property odid#

Original deck ID for cards in filtered deck as pandas.Series of integers.

merge_notes(inplace=False, columns=None, drop_columns=None, prepend='n', prepend_clash_only=True)[source]#

Merge note table into existing dataframe.

Parameters:
  • inplace – If False, return new dataframe, else update old one

  • columns – Columns to merge

  • drop_columns – Columns to ignore when merging

  • prepend – Prepend this string to fields from note table

  • prepend_clash_only – Only prepend the prepend string when column names would otherwise clash.

Returns:

New AnkiDataFrame if inplace==True, else None

merge_cards(inplace=False, columns=None, drop_columns=None, prepend='c', prepend_clash_only=True)[source]#

Merges information from the card table into the current dataframe.

Parameters:
  • inplace – If False, return new dataframe, else update old one

  • columns – Columns to merge

  • drop_columns – Columns to ignore when merging

  • prepend – Prepend this string to fields from card table

  • prepend_clash_only – Only prepend the prepend string when column names would otherwise clash.

Returns:

New AnkiDataFrame if inplace==True, else None

fields_as_columns(inplace=False, force=False)[source]#

In the ‘notes’ table, the field contents of the notes is contained in one column (‘flds’) by default. With this method, this column can be split up into a new column for every field.

Parameters:
  • inplace – If False, return new dataframe, else update old one

  • force – Internal use

Returns:

New pandas.DataFrame if inplace==True, else None

fields_as_list(inplace=False, force=False)[source]#

This reverts fields_as_columns(), all columns that represented field contents are now merged into one column ‘nflds’.

Parameters:
  • inplace – If False, return new dataframe, else update old one

  • force – Internal use

Returns:

New AnkiDataFrame if inplace==True, else None

list_tags() list[str][source]#

Return sorted list of all tags in the current table.

list_decks() list[str][source]#

Return sorted list of deck names in the current table.

list_models()[source]#

Return sorted list of model names in the current table.

has_tag(tags: Iterable[str] | str | None = None)[source]#

Checks whether row has a certain tag (‘ntags’ column).

Parameters:

tags – String or list thereof. In the latter case, True is returned if the row contains any of the specified tags. If None (default), True is returned if the row has any tag at all.

Returns:

Boolean pd.Series

Examples

# Get all tagged notes:
notes[notes.has_tag()]
# Get all untagged notes:
notes[~notes.has_tag()]
# Get all notes tagged Japanese:
japanese_notes = notes[notes.has_tag("Japanese")]
# Get all notes tagged either Japanese or Chinese:
asian_notes = notes[notes.has_tag(["Japanese", "Chinese"])]
has_tags(tags: Iterable[str] | str | None = None)[source]#

Checks whether row contains at least the supplied tags.

Parameters:

tags – String or list thereof. If None (default), True is returned if the row has any tag at all.

Returns:

Boolean pd.Series

Examples

# Get all notes tagged BOTH Japanese or Chinese
bilingual_notes = notes[notes.has_tags(["Japanese", "Chinese"])]
# Note the difference to
asian_notes = notes[notes.has_tag(["Japanese", "Chinese"])]
add_tag(tags: Sequence[str] | str, inplace=False)[source]#

Adds tag (‘ntags’ column).

Parameters:
  • tags – String or list thereof.

  • inplace – If False, return new dataframe, else update old one

Returns:

New AnkiDataFrame if inplace==True, else None

remove_tag(tags: Iterable[str] | str | None, inplace=False)[source]#

Removes tag (‘ntags’ column).

Parameters:
  • tags – String or list thereof. If None, all tags are removed.

  • inplace – If False, return new dataframe, else update old one

Returns:

New AnkiDataFrame if inplace==True, else None

was_modified(other: pd.DataFrame | None = None, na=True, _force=False)[source]#

Compare with original table; show which rows have changed. Will only compare columns existing in both dataframes.

Parameters:
  • other – Compare with this pandas.DataFrame. If None (default), use original unmodified dataframe as reloaded from the database.

  • na – Value for new or deleted columns

  • _force – internal use

Returns:

Boolean value for each row, showing if it was modified.

modified_columns(other: pd.DataFrame | None = None, _force=False, only=True)[source]#

Compare with original table, show which columns in which rows were modified.

Parameters:
  • other – Compare with this pandas.DataFrame. If None (default), use original unmodified dataframe as reloaded from the database.

  • only – Only show rows where at least one column is changed.

  • _force – internal use

Returns:

Boolean value for each row, showing if it was modified. New rows are considered to be modified as well.

was_added(other: pd.DataFrame | None = None, _force=False)[source]#

Compare with original table, show which rows were added.

Parameters:
  • other – Compare with this pandas.DataFrame. If None (default), use original unmodified dataframe as reloaded from the database.

  • _force – internal use

Returns:

Boolean value for each row, showing if it was modified. New rows are considered to be modified as well.

was_deleted(other: pd.DataFrame | None = None, _force=False) list[source]#

Compare with original table, return deleted indizes.

Parameters:
  • other – Compare with this pandas.DataFrame. If None (default), use original unmodified dataframe as reloaded from the database.

  • _force – internal use

Returns:

Sorted list of indizes.

normalize(inplace=False, force=False)[source]#

Bring a AnkiDataFrame from the raw format (i.e. the exact format that Anki uses in its internal representation) to our convenient format.

Parameters:
  • inplace – If False, return new dataframe, else update old one

  • force – If a previous conversion fails, normalize() will refuse to attempt another one by default. Use this option to force it to attempt in anyway.

Returns:

New AnkiDataFrame if inplace==True, else None

raw(inplace=False, force=False)[source]#

Bring a AnkiDataFrame into the raw format (i.e. the exact format that Anki uses in its internal representation) .

Parameters:
  • inplace – If False, return new dataframe, else update old one

  • force – If a previous conversion fails, raw() will refuse to attempt another one by default. Use this option to force it to attempt in anyway.

Returns:

New AnkiDataFrame if inplace==True, else None

summarize_changes(output='print') dict | None[source]#

Summarize changes that were made with respect to the table as loaded from the database.

Parameters:

output – Output mode: ‘print’ (default: print) or ‘dict’ (return as dictionary)

Returns:

None or dictionary

add_card(nid: int, cdeck: str, cord: int | list[int] | None = None, cmod: int | None = None, cusn: int | None = None, cqueue: str | None = None, ctype: str | None = None, civl: int | None = None, cfactor: int | None = None, creps: int | None = None, clapses: int | None = None, cleft: int | None = None, cdue: int | None = None, inplace=False)[source]#

Similar to ankipandas.ankipdf.AnkiDataFrame.add_cards()

Parameters:
  • nid

  • cdeck

  • cord

  • cmod

  • cusn

  • cqueue

  • ctype

  • civl

  • cfactor

  • creps

  • clapses

  • cleft

  • cdue

  • inplace

Returns:

add_cards(nid: list[int], cdeck: str | list[str], cord: int | list[int] | None = None, cmod: int | list[int] | None = None, cusn: int | list[int] | None = None, cqueue: str | list[str] | None = None, ctype: str | list[str] | None = None, civl: int | list[int] | None = None, cfactor: int | list[int] | None = None, creps: int | list[int] | None = None, clapses: int | list[int] | None = None, cleft: int | list[int] | None = None, cdue: int | list[int] | None = None, inplace=False)[source]#

Add cards belonging to notes of one model.

Parameters:
  • nid – Note IDs of the notes that you want to add cards for

  • cdeck – Name of deck to add cards to as string or list of strings (different deck for each nid).

  • cord – Number of the template to add cards for as int or list thereof. The template corresponds to the reviewing direction. If left None (default), cards for all templates will be added. It is not possible to specify different cord for different nids!

  • cmod – List of modification timestamps. Will be set automatically if None (default) and it is discouraged to set your own.

  • cusn – List of Update Sequence Numbers. Will be set automatically (to -1, i.e. needs update) if None (default) and it is very discouraged to set your own.

  • cqueue – ‘sched buried’, ‘user buried’, ‘suspended’, ‘new’, ‘learning’, ‘due’, ‘in learning’ (learning but next rev at least a day after the previous review). If None (default), ‘new’ is chosen for all cards. Specify as string or list thereof.

  • ctype – List of card types (‘learning’, ‘review’, ‘relearn’, ‘cram’). If None (default) ‘learning’ is chosen for all.

  • civl – The new interval that the card was pushed to after the review. Positive values are in days, negative values are in seconds (for learning cards). If None (default) 0 is chosen for all cards.

  • cfactor – The new ease factor of the card in permille. If None (default) 0 is chosen for all.

  • creps – Number of reviews. If None (default), 0 is chosen for all cards.

  • clapses – The number of times the card went from a ‘was answered correctly’ to ‘was answered incorrectly’. If None (default), 0 is chosen for all cards.

  • cleft – Of the form a*1000+b, with: b the number of reps left till graduation and a the number of reps left today. If None (default), 0 is chosen for all cards.

  • cdue – Due is used differently for different card types: new: note id or random int, due: integer day, relative to the collection’s creation time, learning: integer timestamp. If None (default), check that we’re adding a new card and set to note ID.

  • inplace – If False (default), return a new AnkiDataFrame, if True, modify in place and return new card IDs

Returns:

AnkiDataFrame if inplace==True, else list of new card IDs

add_notes(nmodel: str, nflds: list[list[str]] | dict[str, list[str]] | list[dict[str, str]], ntags: list[list[str]] | None = None, nid=None, nguid=None, nmod=None, nusn=None, inplace=False)[source]#

Add multiple new notes corresponding to one model.

Parameters:
  • nmodel – Name of the model (must exist already, check list_models() for a list of available models)

  • nflds – Fields of the note either as list of lists, e.g. [[field1_note1, ... fieldN_note1], ..., [field1_noteM, ... fieldN_noteM]] or dictionary {field name: [field_value1, ..., field_valueM]} or list of dictionaries: [{field_name: field_value for note 1}, ..., {field_name: field_value for note N}]. If dictionaries are used: If fields are not present, they are filled with empty strings.

  • ntags – Tags of the note as list of list of strings: [[tag1_note1, tag2_note1, ... ], ... [tag_1_noteM, ...]]. If None, no tags will be added.

  • nid – List of note IDs. Will be set automatically if None (default) and it is discouraged to set your own.

  • nguid – List of Globally Unique IDs. Will be set automatically if None (default), and it is discouraged to set your own.

  • nmod – List of modification timestamps. Will be set automatically if None (default) and it is discouraged to set your own.

  • nusn – List of Update Sequence Number. Will be set automatically (to -1, i.e. needs update) if None (default) and it is very discouraged to set your own.

  • inplace – If False (default), return a new AnkiDataFrame, if True, modify in place and return new note ID

Returns:

AnkiDataFrame if inplace==True, else new note ID (int)

add_note(nmodel: str, nflds: list[str] | dict[str, str], ntags=None, nid=None, nguid=None, nmod=None, nusn=-1, inplace=False)[source]#

Add new note.

Note

For better performance it is advisable to use add_notes() when adding many notes.

Parameters:
  • nmodel – Name of the model (must exist already, check list_models() for a list of available models)

  • nflds – Fields of the note either as list or as dictionary {field name: field value}. In the latter case, if fields are not present, they are filled with empty strings.

  • ntags – Tags of the note as string or Iterable thereof. Defaults to no tags.

  • nid – Note ID. Will be set automatically by default and it is discouraged to set your own. If you do so and it already exists, the existing note will be overwritten.

  • nguid – Note Globally Unique ID. Will be set automatically by default, and it is discouraged to set your own.

  • nmod – Modification timestamp. Will be set automatically by default and it is discouraged to set your own.

  • nusn – Update sequence number. Will be set automatically (to -1, i.e. needs update) if None (default) and it is very discouraged to set your own.

  • inplace – If False (default), return a new ankipandas.AnkiDataFrame, if True, modify in place and return new note ID

Returns:

ankipandas.AnkiDataFrame if inplace==True, else new note ID (int)

help_col(column, ret=False) str | None[source]#

Show description/help about a column. To get information about all columns, use the help_cols() method instead.

Parameters:
  • column – Name of the column

  • ret – If True, return as string, rather than printing

help_cols(column='auto', table='all', ankicolumn='all') DataFrame[source]#

Show information about the columns and their interpretations. To get information about a single column, please use help_col().

Parameters:
  • column – Name of a field or column (as used by us) or list thereof. If ‘auto’ (default), all columns from the current dataframe will be shown. If ‘all’ no filtering based on the table will be performed

  • table – Possible values: ‘notes’, ‘cards’, ‘revlog’ or list thereof. If ‘all’ no filtering based on the table will be performed

  • ankicolumn – Name of a field or column (as used by Anki) or list thereof. If ‘all’ no filtering based on the table will be performed

Returns:

Pandas DataFrame with all matches.

Warning

As there are problems with text wrapping in pandas DataFrame, this method might change or disappear in the future.

static help(ret=False) str | None[source]#

Display short help text.

Parameters:

ret – Return as string instead of printing it.

Returns:

string if ret==True, else None