【问题标题】:How to clean up CSV file with columns shifted?如何清理列移位的 CSV 文件?
【发布时间】:2018-11-19 11:39:49
【问题描述】:

我有一个正在尝试清理的电影 CSV 文件。我正在使用 Jupyter 笔记本。

它有 10,000 行和 5 列。以下是一些示例数据:

Movie Name      | Genre  | Date Released  | Length        | Rating      |
The Godfather   | Crime  | March 24, 1972 | 175           | R           |
The Avengers    | Action | May 5, 2012    | 143           | PG-13       |
The Dark Knight | Action | Crime          | July 18, 2008 | 152         | PG-13

请注意,对于“黑暗骑士”,由于有 2 个类型,因此行会向右移动。我想清理数据,使该行变为:

The Dark Knight | Action, Crime | July 18, 2008 | 152 | PG-13

我所做的是(在 Jupyter 笔记本中)

import pandas as pd
path = 'movies.csv'
df = pd.read_csv(path, header=0, names=['Movie Name', 'Genre', 'Date Released','Length','Rating','Extra'])

ctrCheck = 0
months = ["January","February","March","April","May","June","July","August","September","October","November","December"]

while ctrCheck < len(df.index):
    check = str(df['Date Released'][ctrCheck])
    if any(month in check for month in months):
        replaceStr = df.loc[ctrCheck, 'Genre'] + "," + df.loc[ctrCheck, 'Date Released']
        df.loc[ctrCheck, 'Genres'] = replaceStr
        df.loc[ctrCheck, 'Date Released'] = df.loc[ctrCheck, 'Length']
        df.loc[ctrCheck, 'Length'] = df.loc[ctrCheck, 'Rating']
        df.loc[ctrCheck, 'Rating'] = df.loc[ctrCheck, 'Extra']
    ctrCheck = ctrCheck + 1

df.drop(labels='Extra', inplace=True, axis='columns')

除了遍历 10,000 行之外,还有更好的方法吗?

谢谢!

【问题讨论】:

  • 不是你问题的答案,但你可以写你的测试if any(month in check for month in ['January', 'February', ...]):
  • 啊,好建议!会这样做:)
  • 您能否提供您正在使用的实际 csv 输入,而不是问题的格式化视图?我确信应该支持 csv 读取格式来读取列表。

标签: python pandas


【解决方案1】:

如果我理解正确,您正在寻找一种不包含显式 for 循环的方法,而是使用矢量化 pandas 方法。

我们可以首先注意到需要转换的行是最后一列中值不是Nan的行

因此我可以建议以下代码:

import pandas as pd

# Name the last unnamed column
df = df.rename(columns={'Unnamed: 5': 'Extra'})

# Save the valid lines in a different dataframe
mask = (df['Extra'].isnull())
df_valid = df[mask]

# Fix the invalid lines
# Fix the Genre
df['Genre'] = df['Genre'] + ' ' + df['Date Released']
# Shift left the columns after 'Genre'
cols = df.columns[:-1]
df.drop('Date Released', axis=1, inplace=True)
df.columns = cols

# Restore valid lines
df.loc[mask, :] = df_valid

生成的数据框:

        Movie Name         Genre  Date Released Length Rating
0    The Godfather         Crime  March 24 1972    175      R
1     The Avengers        Action     May 5 2012    143  PG-13
2  The Dark Knight  Action Crime   July 18 2008    152  PG-13

注意此方法仅在每部电影的最大流派数为 2 时才有效,如果我理解正确的话就是这种情况:)

【讨论】:

  • 谢谢!这工作得很好:) 在解析大量数据时使用这样的方法比使用循环更可取吗?我的印象是这样会更有效率,但我可能错了!
  • 不客气! :) 很高兴能帮到你 :) 我不是时间比较方面的专家,如果有人能确定我将要提出的主张,我会很高兴。 numpy 尤其是 pandas 等库旨在能够处理大数据并有效地对其执行许多操作和算法。这些库也是由许多经验丰富的开发人员和算法开发人员开发的。由于这两个事实,我认为他们提供的方法会比我开发的方法更有效。因此我会说最好使用它们:)
猜你喜欢
  • 1970-01-01
  • 2017-04-08
  • 2016-07-18
  • 1970-01-01
  • 2021-12-27
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 2021-03-05
相关资源
最近更新 更多