【问题标题】:Based on a condition, how to fill columns with column names whose row are not null根据条件,如何用行不为空的列名填充列
【发布时间】:2022-11-17 01:01:17
【问题描述】:

你好,我的问题和这篇文章几乎一样:How to fill in a column with column names whose rows are not NULL in Pandas?

但就我而言,我需要根据列名是国家还是细分来填充列,而不是进行串联。

编辑:表格 原来我有这个:

Segment Country Segment 1 Country 1 Segment 2
Nan Nan 123456 123456 Nan
Nan Nan Nan Nan Nan
Nan Nan Nan 123456 123456
Nan Nan Nan 123456 123456

实际上我有这个(第一列由我代码中最后一行之前的两行填充:

Segment Country Segment 1 Country 1 Segment 2
Seg1 ; Country1 ; Seg1 ; Country1 ; 123456 123456 Nan
Nan Nan Nan Nan Nan
country1 ; seg2 ; country1 ; seg2 ; Nan 123456 123456
country1 ; seg2 ; country1 ; seg2 ; Nan 123456 123456

我需要这个:

Segment Country Segment 1 Country 1 Segment 2
Segment 1 Country1 123456 123456 Nan
Nan Nan Nan Nan Nan
Segment 2 country1 Nan 123456 123456
Segment 2 country1 Nan 123456 123456

编辑:我的代码在尝试整合答案后实际上看起来像这样:错误是:AttributeError: Can only use .str accessor with string values!. Did you mean: 'std'?

#For each column in df, check if there is a value and if yes : first copy the value into the 'Amount' Column, then copy the column name into the 'Segment' or 'Country' columns
for column in df.columns[3:]:
    valueList = df[column][3:].values
    valueList = valueList[~pd.isna(valueList)]
    def detect(d):
        cols = d.columns.values
        dd = pd.DataFrame(columns=cols, index=d.index.unique())
        for col in cols:
            s = d[col].loc[d[col].str.contains(col[0:3], case=False)].str.replace(r'(\w+)(\d+)', col + r'\2')
            dd[col] = s
        return dd

    #Fill amount Column with other columns values if NaN
    if column in isSP:
        df['Amount'].fillna(df[column], inplace = True)
        df['Segment'] = df.iloc[:, 3:].notna().dot(df.columns[3:] + ';' ).str.strip(';')
        df['Country'] = df.iloc[:, 3:].notna().dot(df.columns[3:] + ' ; ' ).str.strip(';')
        df[['Segment', 'Country']] = detect(df[['Segment', 'Country']].apply(lambda x: x.astype(str).str.split(r'\s+[+]\s+').explode()))

非常感谢。

【问题讨论】:

  • 您如何识别给定字符串是细分市场还是国家/地区?
  • 为了确定标题是否是一个段,我使用了这一行:isSP = [col for col in df.columns if "_sp" in col] 对于国家/地区,它是所有其他的,但理想情况下我想使用一个列表Countries.csv(列表在项目的文件夹中)。
  • 段的名称中都有“_sp”

标签: python pandas dataframe


【解决方案1】:

您可以使用以下解决方案。对于此解决方案,我首先定义了一个自定义函数,以根据与列名部分匹配的值过滤前两列,然后将它们替换为完整的列名:

def detect(d):
    cols = d.columns.values
    dd = pd.DataFrame(columns=cols, index=d.index.unique())
    for col in cols:
        s = d[col].loc[d[col].str.contains(col[0:3], case=False)].str.replace(r'(w+)(d+)', col + r'')
        dd[col] = s
    return dd

df[['Segment', 'Country']] = detect(df[['Segment', 'Country']].apply(lambda x: x.astype(str).str.split(';').explode()))
df

    Segment   Country Segment 1 Country 1 Segment 2
0  Segment1  Country1    123456    123456       Nan
1       NaN       NaN       Nan       Nan       Nan
2  Segment2  Country1       Nan    123456    123456
3  Segment2  Country1       Nan    123456    123456

【讨论】:

  • 感谢您的回答,但是我收到此行的以下错误:df[['Segment', 'Country']] = detect(df[['Segment', 'Country']].apply(lambda x: x .str.split(r's+[+]s+').explode())) AttributeError: Can only use .str accessor with string values!.您是指:'std'吗?
  • 我没有得到那个错误。真奇怪。原始数据集中的SegmentCountry 列是否为object 类型?
  • 如果我没记错的话,是的,它们是对象,让我在我的帖子中添加完整的脚本,我还是个初学者,所以也许你会看到一些东西。
  • 我不太明白你的脚本中发生了什么。但是,如果您的原始数据集看起来像您的示例数据,它就可以工作。
  • 我做了:print(type(df['Segment'])) 输出是:<class 'pandas.core.series.Series'> 也许我没有正确实现你的代码?
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 2021-11-24
相关资源
最近更新 更多