如果其他列中的值满足条件,则创建熊猫数据框列

时间:2021-05-19 12:20:27

标签: python pandas dataframe

目前,我有一个这样的数据框:

<头>
索引 类型 上游 下游 标志
1 谷歌 搜索引擎 1 0 NaN
2 英国广播公司新闻 公共广播公司 1 1 中心
3 英国广播公司新闻 公共广播公司 1 1 中心
4 脸书 社交媒体 1 0 NaN
5 福克斯新闻 商业广播公司 1 1 中心

我想实现这样的数据框:

<头>
索引 类型 标志 refer_fb refer_soc_med ref_goog refer_search_eng
1 谷歌 搜索引擎 1 0 NaN NaN NaN NaN NaN
2 英国广播公司新闻 公共广播公司 1 1 中心 0 0 1 1
3 英国广播公司新闻 公共广播公司 1 1 中心 0 0 1 1
4 脸书 社交媒体 1 0 NaN NaN NaN NaN NaN
5 福克斯新闻 商业广播公司 1 1 中心 1 1 0 0

我的脚本需要做的是:

创建新列,当满足上游 = 1,下游 = 0 的条件时,根据前一行对每个新闻项目(始终标记为中心)进行分类。我希望新列中的二进制值。

重要的是,如果 'news' 类型之后的后续行也是由 'center' 标志显示的 'news',那么这也应该与前一个新闻行的分类相同。

1 个答案:

答案 0 :(得分:0)

尝试根据社交媒体和搜索引擎行在表中的位置创建组,并使用布尔索引和 cumsum。然后使用 groupby tranform 'first' 根据每组中的第一行获取引用。

refs

0    search engine
1    search engine
2     social media
Name: type, dtype: object

然后使用 get_dummiesrefs 转换为 1 和 0 指标值。

   search engine  social media
0              1             0
1              1             0
2              0             1

Joindf 中的列保留在新的 DataFrame 中。

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'domain': {0: 'google', 1: 'bbcnews', 2: 'bbcnews', 3: 'facebook',
               4: 'foxnews'},
    'type': {0: 'search engine', 1: 'news', 2: 'news', 3: 'social media',
             4: 'news'}, 'upstream': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1},
    'downstream': {0: 0, 1: 1, 2: 1, 3: 0, 4: 1},
    'flag': {0: np.nan, 1: 'centre', 2: 'centre', 3: np.nan, 4: 'centre'}
})

# Create mask for News Rows
m = df.type.eq('news')
# get first row from each group
refs = df.groupby(
    (~m).cumsum()  # Groups Based on Not News Rows
)['type'].transform('first')[m].reset_index(drop=True)

# Create New DF with columns to keep and the dummies from refs
new_df = df.loc[m, ['domain', 'type']] \
    .reset_index(drop=True) \
    .join(pd.get_dummies(refs)) \
    .rename(columns={'search engine': 'ref_search engine',
                     'social media': 'ref_social media'})

print(new_df)

new_df

    domain  type  ref_search engine  ref_social media
0  bbcnews  news                  1                 0
1  bbcnews  news                  1                 0
2  foxnews  news                  0                 1