74052


### やりたいこと

  
csvファイルのデータを抽出し、全ての列に空白が一つでもあれば除外します。  
その後、特定の列に文字列を追加し、１行ずつループさせてメッセージします。  
今回はB列とC列だけを読み込んで空白が一つでもあれば除外します。

CSVのデータ

[code]

    A       B      C       D
    アメリカ  1234  テキサス 　ワシントン
    カナダ　　空白　バンクーバー 空白
    日本    2345　　東京     空白
    イタリア　3456　　空白     空白
    
[/code]

①先ずは抽出したいデータ下記のように表示します。  
df_i = df[["B","C"]]  
print(df_i)

[code]

    B      C       
    1234  テキサス   
    空白　 バンクーバー
    2345　　東京    
    3456　　空白    
    
[/code]

②BC列の中に空白一つでもあれば除外します。

[code]

    B      C       
    1234  テキサス   
    2345　　東京    
    
[/code]

③下記の形式でデータを加工して文字列を追加します。

[code]

    Number/1234,{Result:テキサス}
    Number/2345,{Result:東京}
    
[/code]

④メールのメッセージに加工したデータを１行ずつ送信します。

[code]

    for j in range(len(message_TEST)):
        subject = "【TEST】"
        message = message_TEST　#←ここに空白を除外したデータをスキップし、1行ずつループさせて加工したデータを入れたいです。
    
[/code]

こちらのコードを記載しましたが下記のように表示されます。

[code]

    from datetime import datetime
    import os
    import json
    import gzip
    from pytz import timezone
    import requests
    import pandas as pd
    from email.mime.text import MIMEText
    import smtplib
    
    #CSVファイルの読み込み
    df1 = pd.read_csv('OK.csv',encoding='utf_8_sig')
    
    #B列の空白を除外
    Number = '\n'.join(filter(None,
      pd.read_csv(
        'OK.csv',
        usecols=['B'],encoding='utf_8_sig', squeeze=True,
        converters={
          'B': lambda x: 'Number/'+x if x else x
        })))
    
    print(Number)
    
    #C列の空白を除外
    Result = '\n'.join(filter(None,
      pd.read_csv(
        'OK.csv',
        usecols=['C'],encoding='utf_8_sig', squeeze=True,
        converters={
          'C': lambda x: 'Result:'+x if x else x
        })))
    
    print(Result)
    
    message_TEST=Number+","+"{"+Result+"}"
    print(message_TEST)
    
    # Authentication settings
    account = "123@gmail.com"
    password = "123"
    
    to_email = "123@gmail.com"
    from_email = "123"
     
    
    for j in range(len(message_TEST)):
        subject = "【TEST】"
        message = message_TEST　#←ここに空白を除外したデータをスキップし、1行ずつループさせて加工したデータを入れたいです。
        msg = MIMEText(message)
        msg["Subject"] = subject
        msg["To"] = to_email
        msg["From"] = from_email
    
        server = smtplib.SMTP("smtp.gmail.com", 587)
        server.starttls()
        server.login(account, password)
        server.send_message(msg)
        server.quit()
    
[/code]

**出力結果**

ここまで出来ましたが、B列に空白ある場合下記のように表示されます。  
B列やC列に空白ある場合、除外するにはどのようにすれば、よろしいでしょうか。

[code]

    Number/1234,{Result__c:テキサス
    Result__c:東京}
    
[/code]

わかる方いらっしゃいましたらご教示願います。  
お手数ですが、宜しくお願いいたします。


CC BY-SA 4.0
2021-02-16T04:29:00.493
74034
2021-02-17T01:48:04.167
2021-02-16T06:36:36.747
3060
18859
question
python csv
PythonでCSVファイルのデータを抽出、全ての列空白を除外


元のデータが 全角の空白 で区切られているので、 データとして 列が区切ることができていない ということをご理解ください。

元のデータさえ適切なものであれば、ご希望の結果が得られると思います。

[code]

    #!/usr/bin/env python3
    #-*- coding: utf-8 -*-↲
    
    import pandas as pd
    from email.mime.text import MIMEText
    import smtplib
    
    #CSVファイルの読み込み
    df1 = pd.read_csv('OK.csv',delimiter=',',encoding='utf_8_sig')
    
    df1 = df1[df1[['B','C']] != '空白']
    df = df1[['B','C']].dropna(axis=0)
    
    for row in df.itertuples():
        print('Number/'+row[1],end='')
        print(',{Result:'+row[2]+'}')
    
[/code]


CC BY-SA 4.0
2021-02-16T10:38:47.833
74049
2021-02-16T15:13:38.443
2021-02-16T15:13:38.443
43957
43957
74034
answer


以下は [pandas.DataFrame.agg](https://pandas.pydata.org/pandas-
docs/stable/reference/api/pandas.DataFrame.agg.html) を使う方法です。

[code]

    import pandas as pd
    
    Result = '\n'.join(
      pd.read_csv('OK.csv',
        usecols=['B', 'C'], dtype=str, encoding='utf_8_sig').
      dropna().
      agg(lambda x: f'Number/{x[0]},{{Result:{x[1]}}}', axis=1))
    
    print(Result)
    =>
    Number/1234,{Result:テキサス}
    Number/2345,{Result:東京}
    
[/code]

**補遺**

> メッセージ内に1行ずつループさせたいですがうまく行かないです。 下記のエラーが表示されます。
>
> `message = '\n'.join([f"{column}\n{data}\n" for column,data in
> Result.iloc[j].iteritems().str])`
>
> error内容
>
> AttributeError: 'str' object has no attribute 'iloc'

その場合はリストにする方がよいかと思います。

[code]

    Result = pd.read_csv(
      'OK.csv', usecols=['B', 'C'], dtype=str, encoding='utf_8_sig')\
      .dropna()\
      .agg(lambda x: f'Number/{x[0]},{{Result:{x[1]}}}', axis=1).tolist()
    
    print(Result)
    =>
    ['Number/1234,{Result:テキサス}', 'Number/2345,{Result:東京}']
    
[/code]

後は `Result` から一個づつ要素(`message`)を取り出せばよろしいかと。

[code]

    for message in Result:
           :
    
[/code]


CC BY-SA 4.0
2021-02-16T11:27:46.803
74052
2021-02-17T01:48:04.167
2021-02-17T01:48:04.167
74034
answer