我想从数据框中的一列中获取匹配项。下面是一个示例:
date tableNameFrom tableNameJoin attributeName
1 29-03-2019 film language [film.languageId, language.languageID]
2 30-03-2019 inventory rental [invetory.inventoryId, rental.filmId]
在上面的示例中,我想在tablenameFrom和tablenameJoin与attributeName之间进行匹配。但是,我想保留日期列。这里是期望的输出:
date tableName attributeName
1 29-03-2019 film languageId
2 29-03-2019 language languageID
3 30-03-2019 inventory inventoryId
4 30-03-2019 rental filmId
任何想法我该怎么办?谢谢。
答案 0 :(得分:2)
这可能不是您想要的,但是会产生给定数据帧的预期输出:
(df.set_index('date').attributeName.apply(pd.Series).stack()
.reset_index().drop('level_1', axis=1).set_index('date')[0]
.str.split('.').apply(pd.Series)
)
它忽略tableNameFrome
和tableNameJoin
,并假定它们在attributeName
中给出。
+----+------------+----------+-------------+
| | date | 0 | 1 |
|----+------------+----------+-------------|
| 0 | 29-03-2019 | film | languageId |
| 1 | 29-03-2019 | language | languageID |
| 2 | 30-03-2019 | invetory | inventoryId |
| 3 | 30-03-2019 | rental | filmId |
+----+------------+----------+-------------+
答案 1 :(得分:1)
原始DataFrame
date tableNameFrom tableNameJoin attributeName
0 29-03-2019 film language [film.languageId, language.languageID]
1 30-03-2019 inventory rental [invetory.inventoryId, rental.filmId]
步骤1-(1)使用attributeName
作为分隔符,将,
分成2个单独的列,(2)删除不需要的方括号([
或]
), (3)删除不必要的列
# 1
df[['tableName','attributeName2']] = df['attributeName'].str.split(',', expand=True)
# 2
df['tableName'] = df['tableName'].str.strip('[')
df['attributeName2'] = df['attributeName2'].str.strip(']')
# 3
df.drop(['attributeName','tableNameFrom','tableNameJoin'], axis=1, inplace=True)
print(df)
date tableName attributeName2
0 29-03-2019 film.languageId language.languageID
1 30-03-2019 invetory.inventoryId rental.filmId
第2步-最后,使用this SO post将列tableName
和attributeName2
中的行拆分为单独的列
df_match = (df.set_index(['date'])
.stack()
.str.split('.', expand=True)
.stack()
.unstack(-1)
.reset_index(-1, drop=True)
.reset_index()
)
df_match.columns = ['date','tableName','attributeName']
print(df_match)
date tableName attributeName
0 29-03-2019 film languageId
1 29-03-2019 language languageID
2 30-03-2019 invetory inventoryId
3 30-03-2019 rental filmId
详细信息
.set_index(['date']
-设置要保留的列作为DataFrame
的索引.stack()
-堆叠行.str.split('.', expand=True)
-按句点(.
调用str.split将这些单元格拆分为单独的列.stack()
-摆脱NULL
的值,因此再次调用stack
.unstack(-1)
unstack(-1)
进行取消堆栈(在最后一级取消堆栈).reset_index(-1, drop=True)
-使用reset_index(-1)
1 这是.unstack(-1)
步骤之前的输出,并解释了为什么我们需要在-1
unstack()
df_intermediate = (df.set_index(['date'])
.stack()
.str.split('.', expand=True)
.stack()
)
print(df_intermediate)
date
29-03-2019 tableName 0 film
1 languageId
attributeName2 0 language
1 languageID
30-03-2019 tableName 0 invetory
1 inventoryId
attributeName2 0 rental
1 filmId
dtype: object
-1
中选择.unstack(-1)
答案 2 :(得分:0)
df.drop(["tableNameFrom","tableNameJoin"],inplace=True)
df2=pd.DataFrame()
for row in df.itertuples():
for i in range(2):
df2=df2.append(pd.Series(
[row[1],"".join(row[2][i].split('.')[0]),"".join(row[2][i].split('.')[1])]).T,ignore_index=True)
df2.columns=["date","tableName","tableAttribute"]
df2
不明白为什么需要中间两列,所以我将它们放下。
答案 3 :(得分:0)
这基本上是一个melt
问题,但有一个中间步骤来清理您的attributeName
列:
# Clean up attributeName column by converting it to string and expanding it by splitting
df = pd.concat([df, df.attributeName.apply(lambda x: ' '.join(x).split('.')[1]).str.split(expand=True)], axis=1)\
.drop('attributeName', axis=1)\
.rename({0:'attribute1', 1:'attribute2'}, axis=1)
这给了我们以下数据框:
print(df)
date tableNameFrom tableNameJoin attribute1 attribute2
0 29-03-2019 film language languageId language
1 30-03-2019 inventory rental inventoryId rental
然后我们可以使用melt
两次来获得所需的输出:
df1 = df.melt(id_vars='date', value_vars=['tableNameFrom', 'tableNameJoin'], value_name='tableName').drop('variable', axis=1)
df2 = df.melt(id_vars='date', value_vars=['attribute1', 'attribute2'], value_name='attributeName').drop(['variable', 'date'], axis=1)
df = pd.concat([df1, df2], axis=1)
哪个给了我们最终的输出:
print(df)
date tableName attributeName
0 29-03-2019 film languageId
1 30-03-2019 inventory inventoryId
2 29-03-2019 language language
3 30-03-2019 rental rental