【问题标题】:Read dataframe split by nan rows and extract specific columns in Python读取由 nan 行拆分的数据框并在 Python 中提取特定列
【发布时间】:2020-11-24 18:33:35
【问题描述】:

我有一个来自here 的示例excel 文件data2.xlsx,它有一个Sheet1,如下所示:

预处理:

2018, 2019, 2020, num 的列是object 类型,我需要将其转换为浮点数:

cols = ['2018', '2019', '2020', 'num']
df[cols].replace('--', np.nan, regex=True).astype(float)

我还需要从bj, sh, gz, sz 和2019-bj-price-quantity, 2019-sh-price-quantity, 2019-gz-price-quantity, 2019-sz-price-quantity 中提取城市名称

pattern = '|'.join(['2019-', '-price-quantity'])
df['city'] = df['city'].str.replace(pattern, '')

最后我需要为每个城市提取nums 中的price 和quantity,并像这样重塑一个新的数据框:

我怎么能在 pandas 中做到这一点?谢谢。

更新:

df = pd.read_excel('./data2.xlsx', sheet_name = 'Sheet1', header = None)
df.groupby(df.iloc[:, 0].isna().cumsum()).transform('first')

输出:

                         0       1       2       3    4
0   2019-bj-price-quantity  2018.0  2019.0  2020.0  num
1   2019-bj-price-quantity  2018.0  2019.0  2020.0  num
2   2019-bj-price-quantity  2018.0  2019.0  2020.0  num
3   2019-bj-price-quantity  2018.0  2019.0  2020.0  num
4   2019-sh-price-quantity  2018.0  2019.0  2020.0  num
5   2019-sh-price-quantity  2018.0  2019.0  2020.0  num
6   2019-sh-price-quantity  2018.0  2019.0  2020.0  num
7   2019-sh-price-quantity  2018.0  2019.0  2020.0  num
8   2019-sh-price-quantity  2018.0  2019.0  2020.0  num
9                      NaN     NaN     NaN     NaN  NaN
10  2019-gz-price-quantity  2018.0  2019.0  2020.0  num
11  2019-gz-price-quantity  2018.0  2019.0  2020.0  num
12  2019-gz-price-quantity  2018.0  2019.0  2020.0  num
13  2019-gz-price-quantity  2018.0  2019.0  2020.0  num
14  2019-gz-price-quantity  2018.0  2019.0  2020.0  num
15                     NaN     NaN     NaN     NaN  NaN
16  2019-sz-price-quantity  2018.0  2019.0  2020.0  num
17  2019-sz-price-quantity  2018.0  2019.0  2020.0  num
18  2019-sz-price-quantity  2018.0  2019.0  2020.0  num
19  2019-sz-price-quantity  2018.0  2019.0  2020.0  num
20  2019-sz-price-quantity  2018.0  2019.0  2020.0  num

参考相关:Read dataframe split by nan rows and reshape them into multiple dataframes in Python

【问题讨论】:

  • 请检查我问题末尾的参考链接,jezrael 提供了很酷的解决方案来阅读Sheet1。

标签: python-3.x pandas dataframe openpyxl


【解决方案1】:

*注意我在列名不确定时使用列索引

您可以使用拆分表

df['city'] = df.groupby(df.iloc[:, 0].isna().cumsum()).transform(first)
df.dropna(subset=df.columns[0], inplace=True)
df = df.loc[df[df.colmns[0]] != df.city]

现在df 将有一个带有表格标题的附加列city,而标题和空行已被丢弃。您可以使用.str.split.str.get 访问该city 列的任何部分

df.city = df.city.str.split('-').str.get(1)

最后你想只保留num 列,这是最简单的一步

df = df.iloc[:, [0, 4, 5]]
df = df.pivot(index='city', columns=df.columns[0], values=df.columns[1])

【讨论】:

  • 你让它工作了吗?我没有测试它,可能有一个错误。这是第一个 pandas.pydata.org/docs/reference/api/… 的文档
  • 我在first 上添加了'',它可以工作。我还更新了您第一行代码的结果,似乎我们无法将其分配为df['city']。
【解决方案2】:

我的代码基于 jezrael 的好答案,欢迎分享更好的解决方案或改进它:

# add header=None for default columns names
df = pd.read_excel('./data2.xlsx', sheet_name = 'Sheet1', header=None)

# convert columns by second row
df.columns = df.iloc[1].rename(None)

# create new column `city` by forward filling non missing values by second column
df.insert(0, 'city', df.iloc[:, 0].mask(df.iloc[:, 1].notna()).ffill())

pattern = '|'.join(['2019-', '-price-quantity'])
df['city'] = df['city'].str.replace(pattern, '')
df['year'] = df['year'].str.replace(pattern, '')
# convert floats to integers 
df.columns = [int(x) if isinstance(x, float) else x for x in df.columns]
df = df[df.year.isin(['price', 'quantity'])]
df = df[['city', 'year', 'num']]
df['num'] = df['num'].replace('--', np.nan, regex=True).astype(float)
df = df.set_index(['city', 'year']).unstack().reset_index()
df.columns = df.columns.droplevel(0)
df.rename({'year': 'city'}, axis=1, inplace=True)
print(df)

输出:

year      price  quantity
0     bj   21.0      10.0
1     gz    6.0      15.0
2     sh   12.0       NaN
3     sz   13.0       NaN

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 2012-04-22
    相关资源
    最近更新 更多