将特定值复制 x 次到新列中

copying specific value x times into a new column

我很难将 excel sheet 中的非结构化数据转换为 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

尝试:

#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

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

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