SPSS Modelerの可変長ファイルノードを、pythonに書き換える

Modelerの可変長ファイルノードを、pythonに書き換えてみます。ここでは、以下の5つのオプションについてフォーカスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/61aaa3fc-0d63-0f30-1abf-bf6a3853eb47.png)

##①ファイルからフィールド名を取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/eac0fcb8-bc71-07bb-56f9-f01a165a9530.png)

Modelerでチェックを入れた場合：
入力ファイルの1行目がヘッダーとみなされ、フィールド名として、取得されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/a60b68f1-d3aa-d7f7-86a3-d11c992ad1a1.png)

Modelerでチェックを外した場合：
入力ファイルの1行目もデータとみなされます。フィールド名としては、fieldnが割り当てられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/0c7b88fa-ba7b-29c6-3e0b-4d67781e879c.png)

:::note warn
注）通常、ヘッダーのないファイルに対してチェックを外しますが、ここでは比較のため、ヘッダーのあるファイルに対してチェックを外しています。
:::

#####Pythonでの書き換え
pandasの関数read_csv()で、なにも引数を設定しないと、1行目がheaderとして認識され、列名columnsに割り当てられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/369168ad-cbe6-087c-bdd5-ad193f8fd5d9.png)

header=Noneとすると、列名columnsに連番が割り当てられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/afd37e39-55df-066e-bf8b-c7e524ea277d.png)

列名を明示的に指定したい場合は、namesオプションを使います。0行目は旧列名が入っていますので、その行は読み込まないようにskiprowsオプションを付けました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/6a0e179f-0158-c43e-0eb2-95af5042fa4d.png)

##②エンコード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/9702d0a4-4562-d270-771d-209f71118f01.png)

Modelerでは、ストリームのデフォルト、システムデフォルト、UTF-8を選択することができます。ストリームのデフォルトでは、以下の画面に示すストリームのオプションで設定したエンコードが利用されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/054b3faf-5f04-c179-3e0f-1d7db59fe191.png)

ここでは、windows環境で、テスト用にshift_jisのファイルを用意しました。

```
天気,気温
晴れ,30
曇り,25
雨,20
```

ストリームのデフォルトでシステムデフォルトを設定した状態で、ストリームのデフォルトを選択した場合、shift_jisのファイルが正しく表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/2ed04211-c28a-9452-47e9-4671f6c2f950.png)

一方、UTF-8を選択した場合、文字化けが発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/16909476-a771-2060-1432-f6d47a1d2dd6.png)

次に少し特殊な文字を表示させてみます。

```
天気,気温
晴れ,30
曇り,25
雨,20
凜,
㌧,
髙,
㈱,
①,
```

問題なく、出力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/45bfba53-c456-c71a-49c9-453ccab222cf.png)

:::note warn
注）LinuxやMacのシステムデフォルトはshift_jisではありません。上述の通り、ModelerではシステムデフォルトかUTF-8しか選択できませんので、shift-jisのファイルを扱う際には事前に文字コードの変更などが必要です。
:::

#####Pythonでの書き換え
エンコーディングは引数encodingで指定します。デフォルトはutf-8で、shift_jisやcp932などを指定できます。

異なるエンコーディングのファイルに対しては、文字化けするのではなく、エラーUnicodeDecodeErrorになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/18cf6e2b-2174-a694-af74-a95d7477df90.png)

encoding="shift_jis" を指定すると、正しく表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/4f6a248a-14ec-4f05-c205-f07363f9c031.png)

次に、少し特殊な文字ですが、エンコードでshift_jisを指定すると、UnicodeDecodeError となりました。cp932を指定することで、Modeler同様、Pythonでも問題なく出力されることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/9f029e91-ef64-240a-319e-c8236bdc2639.png)

##③フィールド区切り文字
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/ddfaf381-3d6a-7afa-b896-f020ce060f1f.png)

Modelerのデフォルトでは、カンマと改行にチェックが入っています。ここでは、以下のデータを用いて、動作を確認してみます。

```
天気,気温
晴れ,30
曇り
雨,20
```

デフォルトの設定では、改行もフィールド区切り文字と設定されているため、フィールド区切り文字として扱われ、以下のように出力されてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/b53acb1f-c880-94a9-acf4-2fa16b138d54.png)

改行を“行区切り”として扱いたい場合、「行区切り文字は改行文字です」にチェックを入れます。これで、期待通りの出力となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/31cefb13-c346-e0b6-5f95-3fd5aee6d00b.png)

次に、区切り文字として使われることが多い | を使ったデータを試してみます。

```
天気|気温
晴れ|30
曇り
雨|20
```

この場合、その他のところに | を入力して、フィールド区切り文字として指定します。期待通りの出力となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/84a28eb7-6b1b-fa7a-2ff0-379f4db7fc34.png)

#####Pythonでの書き換え
Pandasの関数read_csv()では、改行は”行区切り”として扱われ、特にオプションの指定はせずに期待通りの出力となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/4e2dbbe1-ebf0-73c9-53c9-e570d8cd1525.png)

次に区切り文字として | を使ったデータです。read_csv()では、区切り文字の指定は、sepオプションを利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/ff13745b-81c3-5119-124d-557a4ef57272.png)

##④自動的に日付と時間を認識します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/daeaec42-3709-2a34-c1c2-648bfa4c2b0c.png)

すでに以下の記事で紹介してくださっていますので、ここでの説明は省略します。
[SPSS Modelerの日付関連clem関数をPythonで書き換える。][]
[SPSS Modelerの日付関連clem関数をPythonで書き換える。]:https://qiita.com/kawada2017/items/c41f443e5246d331bea1

##⑤引用符
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/4dcf3ea3-20f0-2851-2d3a-a932dbe5d3fa.png)

デフォルトでは、ペアで破棄 が選択されています。この場合、フィールド値は文字列として、引用符なしで保存されます。ここでは、引用符の中に , や改行が含まれるデータで、動作を確認してみます。

```
天気,気温,コメント
晴れ,30,"すごしやすい　天気,気温　です”
曇り
雨,20,"蒸し暑い
天気です"
```

一見、期待通りの出力が得られたように見えますが、引用符中の改行が半角スペースとして表示されました。「蒸し暑い 天気です」となっていますが、このデータをそのまま出力させると、改行されて出力されましたので、内部的には改行コードのまま扱われているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/1f95a4c3-7739-51ab-0909-6c9c4ac6b968.png)

#####Pythonでの書き換え
関数read_csv()でもデフォルト（特にオプションの指定なし）で、引用符は破棄され、引用符なしの文字列として出力されました。ただし、文字列の中で、引用符中の改行は、\r\nとして扱われています。\r\n が不要な場合には、置換する必要があります。ここでは、関数replace()を使用して、\r\nを削除してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690144/0c4af85f-7484-af44-aa0a-450e13529363.png)

##（参考にした情報）
[pandasでcsv/tsvファイル読み込み（read_csv, read_table）][]
[pandasでcsv/tsvファイル読み込み（read_csv, read_table）]:https://note.nkmk.me/python-pandas-read-csv-tsv/

[Python♪Windowsの「Shift JIS」の落とし穴][]
[Python♪Windowsの「Shift JIS」の落とし穴]:https://snowtree-injune.com/2020/05/15/codec-py003/