Python中的多对多数据结构
我有一个关于书籍和作者的数据集,它们之间的关系是多对多的。
这个数据集中大约有一百万本书和十万位作者,每本书平均有十位作者。
我需要对这个数据集进行一系列操作,比如统计每位作者的书籍数量,或者从数据集中删除某位作者的所有书籍。
我想知道有什么好的数据结构可以让我快速处理这些操作。
我希望能找到一些现成的模块,能够提供类似于以下功能的方法:
obj.books.add(book1)
# linking
obj.books[n].author = author1
obj.authors[m].author = book1
# deleting
obj.remove(author1) # should automatically remove all links to the books by author1, but not the linked books
我想说明一下,我更倾向于不使用数据库,而是希望所有操作都在内存中完成。
谢谢!
4 个回答
我建议你直接用 pandas
来处理这些事情。它可以很好地处理多对多的关系。统计和删除数据也非常简单。比如说:
import pandas as pd
# Set up the dataframe with books and authors.
df = pd.DataFrame(columns=['author', 'book'])
df.loc[0] = ['John Smith', 'Programming in Python']
df.loc[1] = ['John Doe', 'Programming in Python']
df.loc[2] = ['John Smith', 'Programming in Pandas']
df.loc[3] = ['John Doe', 'Programming in Numpy']
df.loc[4] = ['Jane Doe', 'Programming in Numpy']
# Find all books by John Smith
print(list(df['John Smith' == df['author']]['book'].values))
# Result: ['Programming in Python', 'Programming in Pandas']
# Use the len function to count the number of books.
# Find all authors for 'Programming in Numpy'
print(list(df['Programming in Numpy' == df['book']]['author'].values))
# Result: ['John Doe', 'Jane Doe']
# To drop the John Doe's from the dataframe:
df = df.drop(df['John Doe' == df['author']].index)
我希望能找到一个现成的模块,里面有一些方法可以用来处理:
既然这个方法已经能正常工作,那你还需要什么呢?
你有一个书籍类(Book)和一个作者类(Author)的定义。还有书籍和作者之间的关系。管理添加、修改和删除这些关系的方法其实只需要几行代码。
创建一个包含作者、书籍和作者-书籍关系的大字典。
用 shelve
来存储这些内容。
就这样完成了。
sqlite3(或者其他好的关系数据库,但sqlite
自带在Python里,处理小数据集时更方便)看起来是你这个任务的合适选择。如果你不想学习SQL的话,SQLAlchemy是一个很流行的“包装器”,可以让你以不同的方式来处理关系数据库,简单来说就是让你可以选择更简单的操作方式。
而“全部在内存中操作”其实没什么问题(不过这有点“傻”,因为你每次运行程序都要从某个地方重新读取所有数据,这样会浪费时间,而把数据库放在磁盘文件里就能省去这个麻烦——但这又是另一个话题;-)。只需把你的sqlite数据库打开为':memory:'
,这样就能得到一个全新的、完全在内存中的关系数据库(只在你程序运行期间有效),整个过程根本不涉及磁盘。
就我个人而言,我会直接使用SQL来完成这个任务——这样我能很好地控制每一步操作,并且可以轻松地添加或删除索引来优化性能等等。你会用到三个表:一个Books
表(主键ID,其他字段比如书名等),一个Authors
表(主键ID,其他字段比如作者名等),还有一个“多对多关系表”,比如叫BookAuthors
,只有两个字段,BookID
和AuthorID
,每个记录对应一本书和一个作者的关系。
BookAuthors
表的两个字段被称为“外键”,分别指向Books
和Authors
表中的ID字段。你可以定义它们为ON DELETE CASCADE
,这样如果某本书或某个作者被删除,相关的记录也会自动删除——这就是“光秃秃”的SQL所能提供的高层次语义,其他数据结构是无法比拟的。