【问题标题】:List vs Dictionary vs Class vs DataFrame in Python Data FormattingPython数据格式中的列表、字典、类和数据框
【发布时间】:2017-11-23 11:21:14
【问题描述】:

我有一个由字符串组成的 Python 列表,其中包含属性地址和每个属性的多个属性。

'Date of Sale', 'January 1, 2017', 'Phone Number', '111-344-2343', 'Color', 'Brown', 'Garage Size', '2', 'Date Listed', 'September 23, 2016', 'Loan From', 'Example Mortgage Services', 'Street Address', '751 Example Drive', 'City', 'Chicago', 'Number of Windows', 'Attorney', 'Shaping LLP', 'Township', 'Dundee', 'Zip Code', '99999', 'List Price', '$83,301.87', 'Bid Amount', '$110,199.00', 'Miscellaneous', 'Long Driveway', 'Date of Sale', ...

这是一个“条目”。该列表在其余属性中以相同的模式继续(每个属性都以“销售日期”开头),但如果字段留空,它们将被完全跳过。例如,如果未进行出价,则“出价金额”后面会直接显示“杂项”,而不是金额。

目标是能够轻松解析信息。例如,我想列出所有我没有出价的房产。

主要问题是使用什么数据格式(class、列表、字典或数据框):

class Property(object):
    def __init__(self,dateOfSale,phoneNumber...):
        self.dateOfSale = 'dateOfSale'
        self.phoneNumber = 'phoneNumber'
        ...

但我不确定如何利用它来获取有关多个属性的信息。

将有关每个属性的所有信息合并到一个list 项中。不过,我不确定您会如何查看这些信息。

使用地址作为键的dictionary,并将所有其他信息作为值,尽管这似乎也不容易重复。

使用 Pandas dataframe。我将不得不做更多的研究,但似乎“电子表格”数据在这种格式下效果很好。

【问题讨论】:

  • 您的示例数据似乎有一个错误:没有与"Number of Windows" 键关联的值。这可能会破坏您尝试对其进行的任何解析。
  • 感谢您的回复@Blckknght 我应该添加更好的评论。一些条目不包含与其关联的值,即使有一个键。如果任何字段没有答案(在本例中为“windows”),则列表中的下一项将只是下一个键。最终,目标是能够找到列表中没有某个键值的所有地址。

标签: list python-3.x class dictionary dataframe


【解决方案1】:

您的数据当前结构非常尴尬,因此我建议您首先将其分解并为每个条目制作一个字典。您可以稍后将字典列表处理成另一个更复杂的数据结构(如DataFrame),但首先进行低级处理要容易得多。

以下是将单个长字符串列表转换为字典列表的方法:

raw_data = ['Date of Sale', 'January 1, 2017',
            'Phone Number', '111-344-2343',
            'Color', 'Brown',
            'Garage Size', '2',
            'Date Listed', 'September 23, 2016',
            'Loan From', 'Example Mortgage Services',
            'Street Address', '751 Example Drive',
            'City', 'Chicago',
            'Number of Windows', '16', # the value was missing for this key, so I made up one
            'Attorney', 'Shaping LLP',
            'Township', 'Dundee',
            'Zip Code', '99999',
            'List Price', '$83,301.87',
            'Bid Amount', '$110,199.00',
            'Miscellaneous', 'Long Driveway',
            'Date of Sale', ...] # this is data for two entries (the second is abbreviated)

list_of_dicts = []
for key, value in zip(*[iter(raw_data)]*2): # iterate on pairs of items from the raw list
    if key == "Date of Sale":
        current_dict = {}  # create a new dict each time we come across a Date of Sale key
        list_of_dicts.append(current_dict)
    current_dict[key] = value

我对 Pandas 完全没有经验,但我怀疑你可以很容易地从 dicts 列表中创建一个数据框(也许只是通过将列表作为参数传递给 DataFrame 构造函数,我不确定)。您可能需要传递额外的参数来描述您希望数据包含的所有列,尤其是如果并非所有条目都具有所有列的值。

【讨论】:

  • 谢谢。您将如何处理缺失值?
  • 哦,我以为当您说缺少某些值时,您的意思是如果该键没有数据,则键和值都不会包含在内。如果只是缺少值,那么我上面在重复迭代器上使用zip 的方法根本不起作用。您需要提前知道所有键的名称,并检查每个值是否是下一个键的名称。真的很乱。您是否可以控制列表的生成方式?如果您正在解析某些内容,则可能能够在较早的时候解决问题,从而降低难度。
  • 这样的事情怎么样? list_of_dicts = [] for key, value in zip(*[iter(raw_data)]*2): # iterate on pairs of items from the raw list if key == "Date of Sale": current_dict = {} # create a new dict each time we come across a Date of Sale key if value == "Date of Sale" or "Phone Number" or "Color" or "Garage Size"... #abbreviating the rest of the keys: value = '' #How do I continue the iteration with next key, rather than skipping it and getting out of order? list_of_dicts.append(current_dict) current_dict[key] = value
【解决方案2】:

除非您确实需要进行数据分析(KISS 原则),否则我不会使用 Pandas DataFrame。我可能会使用 namedtuple 而不是 dict 的列表,因为它在语法上更简洁,例如:

import csv
from collections import namedtuple
Property = namedtuple('Property', 'date_of_sale phone_number ...')

properties = []
with open('propertydata.csv', newline='') as csvfile:
    for record in csv.reader(csvfile):
         properties.append(Property(*record))

然后你可以遍历属性并做任何你需要的事情:

no_bid_properties = [p for p in properties where not p.bid_amount]

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 2020-02-04
    • 2022-11-29
    • 2021-08-14
    • 1970-01-01
    • 2021-06-11
    相关资源
    最近更新 更多