【问题标题】:copying specific value x times into a new column将特定值 x 次复制到新列中
【发布时间】:2021-11-29 21:10:43
【问题描述】:

我很难将 Excel 工作表中的非结构化数据转换为 Python 中的结构化表格格式,以便对其进行数据分析。

我想将位置(即巴黎)复制到 Col 4 到其相应的行。 # of x 下面的行代表一个人,可能会有所不同。例如,米兰有 3 个条目,而伦敦有 4 个。

此外,删除没有像 Paris 和 Rome 这样的条目的行。

我有点想法,但不知道如何实施。如果Col 2 不是# of Cafes to Visit 或不是数字,则将该值复制到Col 4 中,直到找到下一个条目...不过对此不确定:(

有人可以帮我吗?

输入:

Col 1 Col 2 Col 3 Col 4
Location Paris
# of Shops To Visit # of Cafes to Visit # of Museums to Visit
Location Milan
# of Shops To Visit # of Cafes to Visit # of Museums to Visit
3 5 3
2 4 4
5 6 7
Location London
# of Shops To Visit # of Cafes to Visit # of Museums to Visit
6 6 2
3 5 0
5 4 1
5 4 1
Location Rome
# of Shops To Visit # of Cafes to Visit # of Museums to Visit

输出:

Col 1 Col 2 Col 3 Col 4
3 5 3 Milan
2 4 4 Milan
5 6 7 Milan
6 6 2 London
3 5 0 London
5 4 1 London
5 4 1 London

【问题讨论】:

    标签: python pandas data-transform


    【解决方案1】:

    为了解决这个问题,我首先单独收集了城市:

    data = pd.read_csv(path,delim_whitespace=True,header=None,names=['col1','col2','col3'])
    cities = data[data['col1']=='Location']['col2'].reset_index(drop=True) 
    

    然后我通过查找 'col3' 中的数据何时不为空来确定将适用于上述数据系列中的每个城市的行:

    city_inds = np.cumsum(np.logical_not(pd.notna(data['col3'])))-1
    

    最后,您可以将这些索引用于原始城市数据系列,以将正确的城市分配到原始数据帧中。然后,我们可以删除不相关的行:

    data['cities'] = cities.iloc[city_inds].reset_index(drop=True)
    data = data[data['col1'].str.isnumeric()].reset_index(drop=True)  #drop rows which aren't numeric in col1
    Out[]:   col1 col2 col3  cities
    0     3    5    3   Milan
    1     2    4    4   Milan
    2     5    6    7   Milan
    3     6    6    2  London
    4    3    5    0  London
    5    5    4    1  London
    6    5    4    1  London
    

    【讨论】:

    • 谢谢! :) 我查看了city_inds = np.cumsum(np.logical_not(pd.notna(data['col3'])))-1 中使用的所有三个函数的文档,但我很困惑当它是一个新城市时它如何能够保持计数和更新。你介意解释一下吗? @jhso
    • 1.当数据为空时,notna 将返回 False(我们正在寻找的内容,因为它指示位置和城市在该行中)。 2.logical_not 翻转它,因此我们在 NaN 所在的位置为 True。 3. 每次我们在此列中看到 NaN 时,Cumsum 都会递增,这将为我们提供城市 DataFrame 中所有数字数据的城市索引(减去 1,因此它从 0 开始)。
    【解决方案2】:

    试试:

    #Removing the rows with no entries like Paris and Rome.
    df['dummy'] = df['Col 2'].replace('# of Cafes to Visit|[0-9]+', np.nan, regex=True).ffill()
    df = df.groupby('dummy').filter(lambda x: len(x) > 2).drop(columns=['dummy'])
    
    #Moving Locations to Col 4
    df['Col 4'].fillna(df['Col 2'], inplace=True)
    df['Col 4'].replace('# of Cafes to Visit|[0-9]+', np.nan, regex=True, inplace=True)
    df['Col 4'].ffill(inplace=True)
    
    df = df[~df['Col 1'].isin(['# of Shops To Visit', 'Location'])]
    df[['Col 1', 'Col 2', 'Col 3']] = df[['Col 1', 'Col 2', 'Col 3']].replace(r'\D+', np.nan, regex=True)
    df.reset_index(drop=True, inplace=True)
    

    输出:

      Col 1 Col 2 Col 3   Col 4
    0     3     5     3   Milan
    1     2     4     4   Milan
    2     5     6     7   Milan
    3     6     6     2  London
    4     3     5     0  London
    5     5     4     1  London
    6     5     4     1  London
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 2021-11-21
      • 1970-01-01
      相关资源
      最近更新 更多