python - 在 pandas、OOP 类和字典之间进行选择 (Python)

标签 python class oop pandas dictionary

我编写了一个程序来读取几个 .csv 文件(它们并不大,每个文件几千行),我进行了一些数据清理和整理,这是每个 .csv 文件的最终结构(虚假数据仅供说明之用)。

import pandas as pd
data = [[112233, 'Rob', 99], [445566, 'John', 88]]
managers = pd.DataFrame(data)
managers.columns = ['ManagerId', 'ManagerName', 'ShopId']
print managers

   ManagerId ManagerName  ShopId
0     112233         Rob      99
1     445566        John      88


data = [[99, 'Shop1'], [88, 'Shop2']]
shops = pd.DataFrame(data)
shops.columns = ['ShopId', 'ShopName']
print shops

   ShopId ShopName
0      99    Shop1
1      88    Shop2

data = [[99, 2000, 3000, 4000], [88, 2500, 3500, 4500]]
sales = pd.DataFrame(data)
sales.columns = ['ShopId', 'Year2010', 'Year2011', 'Year2012']
print sales

   ShopId  Year2010  Year2011  Year2012
0      99      2000      3000      4000
1      88      2500      3500      4500

然后我使用 xlsxwriterreportlab Python 包在迭代数据框的同时创建自定义 Excel 工作表和 .pdf 报告。一切看起来都很棒,所有命名的包都很好地完成了它们的工作。

但我担心的是,我觉得我的代码很难维护,因为我需要在多次调用中多次访问相同的数据框行。

假设我需要获取负责 2010 年销售额超过 1500 的商店的经理姓名。我的代码充满了这种调用:

managers[managers['ShopId'].isin(
    sales[sales['Year2010'] > 1500]['ShopId'])]['ManagerName'].values
>>> array(['Rob', 'John'], dtype=object)

我认为在阅读这行代码时很难看出发生了什么。我可以创建多个中间变量,但这会添加多行代码。

牺牲数据库规范化思想并将所有部分合并到一个数据框架中以获得更易于维护的代码有多常见?拥有单个数据框显然有缺点,因为在尝试合并以后可能需要的其他数据框时,它可能会变得困惑。合并它们当然会导致数据冗余,因为同一位经理可能被分配到多个商店。

df = managers.merge(sales, how='left', on='ShopId').
    merge(shops, how='left', on='ShopId')
print df

   ManagerId ManagerName  ShopId  Year2010  Year2011  Year2012 ShopName
0     112233         Rob      99      2000      3000      4000    Shop1
1     445566        John      88      2500      3500      4500    Shop2

至少这个调用变小了:

df[df['Year2010'] > 1500]['ManagerName'].values
>>> array(['Rob', 'John'], dtype=object)

也许 pandas 是这种工作的错误工具?

办公室的 C# 开发人员对我皱眉并告诉我使用这些类,但我会有一堆方法,如 get_manager_sales(managerid) 等等。为报告迭代类实例听起来也很麻烦,因为我需要实现一些排序和索引(我通过 pandas 免费获得)。

字典可以工作,但它也使修改现有数据、进行合并等变得困难。语法也没有变得更好。

data_dict = df.to_dict('records')
[{'ManagerId': 112233L,
  'ManagerName': 'Rob',
  'ShopId': 99L,
  'ShopName': 'Shop1',
  'Year2010': 2000L,
  'Year2011': 3000L,
  'Year2012': 4000L},
 {'ManagerId': 445566L,
  'ManagerName': 'John',
  'ShopId': 88L,
  'ShopName': 'Shop2',
  'Year2010': 2500L,
  'Year2011': 3500L,
  'Year2012': 4500L}]

获取负责 2010 年销售额超过 1500 的商店的经理姓名。

[row['ManagerName'] for row in data_dict if row['Year2010'] > 1500]
>>> ['Rob', 'John']

在我处理数据的这种特殊情况下,我应该一直使用 pandas 还是有另一种方法来编写更清晰的代码,同时利用 的强大功能> Pandas ?

最佳答案

我会选择 Pandas,因为它速度更快,具有优秀且极其丰富的 API,源代码看起来更干净更好,等等。

顺便说一句,下面这行可以很容易地重写:

managers[managers['ShopId'].isin(sales[sales['Year2010'] > 1500]['ShopId'])]['ManagerName'].values

作为:

ShopIds = sales.ix[sales['Year2010'] > 1500, 'ShopId']
managers.query('ShopId in @ShopIds')['ManagerName'].values

IMO 它很容易阅读和理解

PS 你可能还想将数据存储在支持 SQL 的数据库中并使用 SQL 或将其存储在 HDF Store 中并使用 where 参数 - 在这两种情况下您可以从索引“搜索”列中受益

关于python - 在 pandas、OOP 类和字典之间进行选择 (Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40041845/

相关文章:

python - 如何删除时间戳中的某些字符串值

python - 如何隐藏机器人框架代码库并仅将二进制文件共享给客户端?

java - 了解 Java 小程序

c++ - 带有 2 个列表的面向对象

javascript - 使用 React hooks 将基于类的组件转换为功能组件

oop - 单一职责原则是 OOP 的规则吗?

python - Werkzeug 属性错误 : 'module' object has no attribute 'InteractiveInterpreter'

python - 为seaborn的线图中图表下方的区域着色?

python - 实现特定于类的方法但不直接使用属性的最佳方式

java - 重写等于父类(super class)但不等于子类?