【问题标题】:Looping through columns using number in column name使用列名中的数字循环遍历列
【发布时间】:2019-02-25 11:12:17
【问题描述】:

我的 pandas 数据框中有以下列 - client_1_name、client_2_name、clinet_3_name...一直到 client_10_name。

我想使用列名中的数字遍历列名,以确定特定列是否包含子字符串 - “Nike”。

我将如何理想地解决问题:

for i in range(1,10):
 df['Nike'] = df['Client_'+i+'_name'].str.contains('Nike', regex = True)

但我收到以下错误

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-85-28926af604a8> in <module>()
          2 
          3 for i in range(1,10):
    ----> 4     df_nike['Nike'] = df_nike['client_'+i+'_name'].str.contains('Nike', regex = True)

TypeError: can only concatenate str (not "int") to str

关于如何做到这一点的建议?

【问题讨论】:

    标签: python regex string pandas


    【解决方案1】:

    你必须在连接之前将整数转换为字符串

    for i in range(1,10):
    # added `str()` around the `i`
        df['Nike'] = df['Client_'+str(i)+'_name'].str.contains('Nike', regex = True)
    

    如果您使用的是 Python 3.6+,则可以使用 f 个字符串

    for i in range(1,10):
    # added `f` at the beginning of the string and {} around `i`
        df['Nike'] = df[f'Client_{i}_name'].str.contains('Nike', regex = True)
    

    正如@Wen-Ben 在他的回答的第二部分中提到的那样,遍历列将导致覆盖您的新“Nike”列。如果您真的想检查所有列而不覆盖“Nike”,您应该像这样将i 添加到列名

    for i in range(1,10):
    # added `f` at the beginning of the string and {} around `i`
        df[f'Nike{i}'] = df[f'Client_{i}_name'].str.contains('Nike', regex = True)
    

    【讨论】:

    • 漂亮,效果很好。你能给我指出一些关于这个 f' 的文档吗?它是如何工作的?
    • 当然。看起来它是用 PEP 498 写的 --> python.org/dev/peps/pep-0498
    • 我想我有一个问题,如果 Client_1_name 包含“Nike”,但 Client_10_name 不包含,df['Nike'] 将返回 0,而不是 1,对吗?我如何指定“这些列中的任何一个”?
    【解决方案2】:

    不确定你需要做什么,但简单地修复你的代码添加str

    for i in range(1,10):
       df['Nike'] = df['Client_'+str(i)+'_name'].str.contains('Nike', regex = True) # notice here you assign the value to one columns 10 times 
    

    你可能想要

    for i in range(1,10):
       df['Nike'+str(i)] = df['Client_'+str(i)+'_name'].str.contains('Nike', regex = True)
    

    【讨论】:

    • 我想我有一个问题,如果 Client_1_name 包含“Nike”,但 Client_10_name 不包含,df['Nike'] 将返回 0,而不是 1,对吗?我如何指定“这些列中的任何一个”?
    【解决方案3】:

    考虑这个数据框,

    df = pd.DataFrame(data = np.random.choice(list('ABCDEFGH')+['Nike'], 100).reshape(10,10), columns = ['Client_'+str(i)+'_name' for i in range(1,11)])
    

    您可以使用检查列是否包含耐克

    df.eq('Nike').any()
    
    Client_1_name      True
    Client_2_name     False
    Client_3_name     False
    Client_4_name      True
    Client_5_name     False
    Client_6_name      True
    Client_7_name      True
    Client_8_name      True
    Client_9_name      True
    Client_10_name     True
    

    如果要提取列名,请尝试

    s = df.eq('Nike').any()
    s[s].index
    
    Index(['Client_1_name', 'Client_4_name', 'Client_6_name', 'Client_7_name',
       'Client_8_name', 'Client_9_name', 'Client_10_name'],
      dtype='object')
    

    如果您只想提取数字,请尝试

    s[s].index.str.extract('(\d+)').astype(int).values.ravel().tolist()
    
    [1, 4, 6, 7, 8, 9, 10]
    

    【讨论】:

      猜你喜欢
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 2018-09-28
      • 1970-01-01
      • 2019-09-07
      • 2020-11-07
      • 2014-06-27
      相关资源
      最近更新 更多