Gabungkan dua kolom teks dalam bingkai data dalam panda / python


487

Saya memiliki 20 x 4000 dataframe di Python menggunakan panda. Dua kolom ini diberi nama Yeardan quarter. Saya ingin membuat variabel bernama periodmake Year = 2000and quarter= q2into 2000q2.

Adakah yang bisa membantu dengan itu?

Jawaban:


531

jika kedua kolom adalah string, Anda dapat menggabungkannya secara langsung:

df["period"] = df["Year"] + df["quarter"]

Jika salah satu (atau keduanya) dari kolom tidak diketik string, Anda harus mengubahnya terlebih dahulu,

df["period"] = df["Year"].astype(str) + df["quarter"]

Waspadalah terhadap NaN saat melakukan ini!


Jika Anda harus bergabung dengan beberapa kolom string, Anda dapat menggunakan agg:

df['period'] = df[['Year', 'quarter', ...]].agg('-'.join, axis=1)

Di mana "-" adalah pemisah.


13
Apakah mungkin untuk menambahkan beberapa kolom bersama tanpa mengetik semua kolom? Katakanlah add(dataframe.iloc[:, 0:10])misalnya?
Heisenberg

5
@ Heisenberg Itu mungkin dengan Python builtin sum.
silvado

6
@silvado, bisakah Anda membuat contoh untuk menambahkan beberapa kolom? Terima kasih
c1c1c1

6
Hati-hati, Anda perlu menerapkan peta (str) ke semua kolom yang bukan string di tempat pertama. jika seperempat adalah angka yang akan Anda lakukan dataframe["period"] = dataframe["Year"].map(str) + dataframe["quarter"].map(str)peta hanya menerapkan konversi string ke semua entri.
Ozgur Ozturk

13
Solusi ini dapat menciptakan masalah jika Anda memiliki nilai nan, dan hati

269
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})
df['period'] = df[['Year', 'quarter']].apply(lambda x: ''.join(x), axis=1)

Menghasilkan kerangka data ini

   Year quarter  period
0  2014      q1  2014q1
1  2015      q2  2015q2

Metode ini menggeneralisasi ke jumlah kolom string yang sewenang-wenang dengan mengganti df[['Year', 'quarter']]dengan setiap potongan kolom dari kerangka data Anda, misalnyadf.iloc[:,0:2].apply(lambda x: ''.join(x), axis=1) .

Anda dapat memeriksa informasi lebih lanjut tentang metode apply () di sini


20
lambda x: ''.join(x)hanya saja ''.join, bukan?
DSM

6
@ OzgurOzturk: ​​intinya adalah bahwa bagian lambda dari lambda x: ''.join(x)konstruksi tidak melakukan apa-apa; itu seperti menggunakan lambda x: sum(x)bukan hanya sum.
DSM

4
Dikonfirmasi hasil yang sama saat menggunakan ''.join, yaitu: df['period'] = df[['Year', 'quarter']].apply(''.join, axis=1).
Max Ghenis

1
@Archie joinhanya mengambil strcontoh dalam iterable. Gunakan mapuntuk mengonversikan semuanya menjadi strdan kemudian gunakan join.
John Strood

16
'-'. join (x.map (str))
Manjul

257

Kumpulan data kecil (<150 baris)

[''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]

atau sedikit lebih lambat tetapi lebih kompak:

df.Year.str.cat(df.quarter)

Kumpulan data yang lebih besar (> 150 baris)

df['Year'].astype(str) + df['quarter']

UPDATE: Grafik waktu Pandas 0.23.4

masukkan deskripsi gambar di sini

Mari kita uji pada 200K baris DF:

In [250]: df
Out[250]:
   Year quarter
0  2014      q1
1  2015      q2

In [251]: df = pd.concat([df] * 10**5)

In [252]: df.shape
Out[252]: (200000, 2)

MEMPERBARUI: timing baru menggunakan Pandas 0.19.0

Pengaturan waktu tanpa pengoptimalan CPU / GPU (diurutkan dari yang tercepat ke yang paling lambat):

In [107]: %timeit df['Year'].astype(str) + df['quarter']
10 loops, best of 3: 131 ms per loop

In [106]: %timeit df['Year'].map(str) + df['quarter']
10 loops, best of 3: 161 ms per loop

In [108]: %timeit df.Year.str.cat(df.quarter)
10 loops, best of 3: 189 ms per loop

In [109]: %timeit df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 567 ms per loop

In [110]: %timeit df[['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 584 ms per loop

In [111]: %timeit df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
1 loop, best of 3: 24.7 s per loop

Pengaturan waktu menggunakan pengoptimalan CPU / GPU:

In [113]: %timeit df['Year'].astype(str) + df['quarter']
10 loops, best of 3: 53.3 ms per loop

In [114]: %timeit df['Year'].map(str) + df['quarter']
10 loops, best of 3: 65.5 ms per loop

In [115]: %timeit df.Year.str.cat(df.quarter)
10 loops, best of 3: 79.9 ms per loop

In [116]: %timeit df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 230 ms per loop

In [117]: %timeit df[['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 230 ms per loop

In [118]: %timeit df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
1 loop, best of 3: 9.38 s per loop

Jawab kontribusi oleh @ anton-vbr


Apa perbedaan antara 261 dan 264 dalam waktu Anda?
Anton Protopopov

@AntonProtopopov rupanya 100 ms entah dari mana :)
Dennis Golomazov

@AntonProtopopov, saya kira itu adalah campuran dari dua timing - satu menggunakan optimasi CPU / GPU, yang lain tidak. Saya telah memperbarui jawaban saya dan meletakkan kedua set waktu di sana ...
Maks

Penggunaan .sum () ini gagal Jika semua kolom tampak seperti bilangan bulat (yaitu bentuk string bilangan bulat). Sebaliknya, tampaknya panda mengubahnya kembali menjadi numerik sebelum menjumlahkan!
CPBL

@ CPBL, coba pendekatan ini:df.T.apply(lambda x: x.str.cat(sep=''))
Maks

157

Metode cat()dari .straccessor bekerja dengan sangat baik untuk ini:

>>> import pandas as pd
>>> df = pd.DataFrame([["2014", "q1"], 
...                    ["2015", "q3"]],
...                   columns=('Year', 'Quarter'))
>>> print(df)
   Year Quarter
0  2014      q1
1  2015      q3
>>> df['Period'] = df.Year.str.cat(df.Quarter)
>>> print(df)
   Year Quarter  Period
0  2014      q1  2014q1
1  2015      q3  2015q3

cat() bahkan memungkinkan Anda untuk menambahkan pemisah jadi, misalnya, misalkan Anda hanya memiliki bilangan bulat untuk tahun dan periode, Anda dapat melakukan ini:

>>> import pandas as pd
>>> df = pd.DataFrame([[2014, 1],
...                    [2015, 3]],
...                   columns=('Year', 'Quarter'))
>>> print(df)
   Year Quarter
0  2014       1
1  2015       3
>>> df['Period'] = df.Year.astype(str).str.cat(df.Quarter.astype(str), sep='q')
>>> print(df)
   Year Quarter  Period
0  2014       1  2014q1
1  2015       3  2015q3

Bergabung dengan banyak kolom hanyalah masalah meneruskan daftar seri atau bingkai data yang berisi semua kecuali kolom pertama sebagai parameter untuk str.cat()dipanggil pada kolom pertama (Seri):

>>> df = pd.DataFrame(
...     [['USA', 'Nevada', 'Las Vegas'],
...      ['Brazil', 'Pernambuco', 'Recife']],
...     columns=['Country', 'State', 'City'],
... )
>>> df['AllTogether'] = df['Country'].str.cat(df[['State', 'City']], sep=' - ')
>>> print(df)
  Country       State       City                   AllTogether
0     USA      Nevada  Las Vegas      USA - Nevada - Las Vegas
1  Brazil  Pernambuco     Recife  Brazil - Pernambuco - Recife

Perhatikan bahwa jika bingkai / seri data panda Anda memiliki nilai nol, Anda harus menyertakan parameter na_rep untuk mengganti nilai NaN dengan string, jika tidak, kolom gabungan akan default ke NaN.


12
Ini tampaknya jauh lebih baik (mungkin lebih efisien juga) daripada lambdaatau map; juga hanya terbaca paling bersih.
dwanderson

1
@ Zak, dengan meneruskan kolom yang tersisa sebagai kerangka data, bukan seri sebagai parameter pertama str.cat(). Saya akan mengubah jawabannya
LeoRochael

Versi panda mana yang Anda gunakan? Saya mendapatkan ValueError: Apakah Anda bermaksud memberikan sepkata kunci? dalam panda-0.23.4. Terima kasih!
Qinqing Liu

@QinqingLiu, saya menguji ulang ini dengan panda-0.23.4 dan sepertinya berhasil. The sepparameter hanya diperlukan jika Anda berniat untuk memisahkan bagian-bagian dari string bersambung. Jika Anda mendapatkan kesalahan, tolong tunjukkan kepada kami contoh Anda yang gagal.
LeoRochael

31

Penggunaan fungsi lamba kali ini dengan string.format ().

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'Quarter': ['q1', 'q2']})
print df
df['YearQuarter'] = df[['Year','Quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
print df

  Quarter  Year
0      q1  2014
1      q2  2015
  Quarter  Year YearQuarter
0      q1  2014      2014q1
1      q2  2015      2015q2

Ini memungkinkan Anda untuk bekerja dengan nilai-nilai non-string dan memformat ulang sesuai kebutuhan.

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'Quarter': [1, 2]})
print df.dtypes
print df

df['YearQuarter'] = df[['Year','Quarter']].apply(lambda x : '{}q{}'.format(x[0],x[1]), axis=1)
print df

Quarter     int64
Year       object
dtype: object
   Quarter  Year
0        1  2014
1        2  2015
   Quarter  Year YearQuarter
0        1  2014      2014q1
1        2  2015      2015q2

1
Jauh lebih cepat: .apply (''. Join (x), axis = 1)
Ghanem

19

Jawaban sederhana untuk pertanyaan Anda.

    year    quarter
0   2000    q1
1   2000    q2

> df['year_quarter'] = df['year'] + '' + df['quarter']

> print(df['year_quarter'])
  2000q1
  2000q2

3
akan gagal jika Yearbukan string
geher

4
gunakandf['Year'].astype(str) + '' + df['quarter'].astype(str)
Yedhrab

2
Apa sebenarnya inti dari solusi ini, karena identik dengan jawaban teratas?
AMC

14

Meskipun jawaban @silvado baik jika Anda mengubah df.map(str)untuk df.astype(str)itu akan lebih cepat:

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})

In [131]: %timeit df["Year"].map(str)
10000 loops, best of 3: 132 us per loop

In [132]: %timeit df["Year"].astype(str)
10000 loops, best of 3: 82.2 us per loop

12

Mari kita misalkan Anda dataframeyaitu dfdengan kolom Yeardan Quarter.

import pandas as pd
df = pd.DataFrame({'Quarter':'q1 q2 q3 q4'.split(), 'Year':'2000'})

Misalkan kita ingin melihat kerangka data;

df
>>>  Quarter    Year
   0    q1      2000
   1    q2      2000
   2    q3      2000
   3    q4      2000

Akhirnya, gabungkan Yeardan Quartersebagai berikut.

df['Period'] = df['Year'] + ' ' + df['Quarter']

Anda sekarang print df dapat melihat kerangka data yang dihasilkan.

df
>>>  Quarter    Year    Period
    0   q1      2000    2000 q1
    1   q2      2000    2000 q2
    2   q3      2000    2000 q3
    3   q4      2000    2000 q4

Jika Anda tidak ingin ruang antara tahun dan kuartal, cukup hapus dengan melakukan;

df['Period'] = df['Year'] + df['Quarter']

3
Ditentukan sebagai stringdf['Period'] = df['Year'].map(str) + df['Quarter'].map(str)
Stuber

Saya mendapatkan TypeError: Series cannot perform the operation +ketika saya menjalankan salah satu df2['filename'] = df2['job_number'] + '.' + df2['task_number']atau df2['filename'] = df2['job_number'].map(str) + '.' + df2['task_number'].map(str).
Karl Baker

Namun, df2['filename'] = df2['job_number'].astype(str) + '.' + df2['task_number'].astype(str)berhasil.
Karl Baker

@KarlBaker, saya pikir Anda tidak memiliki string dalam input Anda. Tapi saya senang Anda tahu itu. Jika Anda melihat contoh dataframeyang saya buat di atas, Anda akan melihat bahwa semua kolom adalah strings.
Samuel Nde

Apa sebenarnya inti dari solusi ini, karena identik dengan jawaban teratas?
AMC

10

Berikut ini adalah implementasi yang menurut saya sangat serbaguna:

In [1]: import pandas as pd 

In [2]: df = pd.DataFrame([[0, 'the', 'quick', 'brown'],
   ...:                    [1, 'fox', 'jumps', 'over'], 
   ...:                    [2, 'the', 'lazy', 'dog']],
   ...:                   columns=['c0', 'c1', 'c2', 'c3'])

In [3]: def str_join(df, sep, *cols):
   ...:     from functools import reduce
   ...:     return reduce(lambda x, y: x.astype(str).str.cat(y.astype(str), sep=sep), 
   ...:                   [df[col] for col in cols])
   ...: 

In [4]: df['cat'] = str_join(df, '-', 'c0', 'c1', 'c2', 'c3')

In [5]: df
Out[5]: 
   c0   c1     c2     c3                cat
0   0  the  quick  brown  0-the-quick-brown
1   1  fox  jumps   over   1-fox-jumps-over
2   2  the   lazy    dog     2-the-lazy-dog

FYI: Metode ini bekerja sangat baik dengan Python 3, tetapi memberi saya masalah dengan Python 2.
Alex P. Miller

10

Saat data Anda dimasukkan ke dalam kerangka data, perintah ini akan menyelesaikan masalah Anda:

df['period'] = df[['Year', 'quarter']].apply(lambda x: ' '.join(x.astype(str)), axis=1)

Jawaban ini identik dengan yang lebih tua, lebih populer .
AMC

9

lebih efisien

def concat_df_str1(df):
    """ run time: 1.3416s """
    return pd.Series([''.join(row.astype(str)) for row in df.values], index=df.index)

dan ini adalah tes waktu:

import numpy as np
import pandas as pd

from time import time


def concat_df_str1(df):
    """ run time: 1.3416s """
    return pd.Series([''.join(row.astype(str)) for row in df.values], index=df.index)


def concat_df_str2(df):
    """ run time: 5.2758s """
    return df.astype(str).sum(axis=1)


def concat_df_str3(df):
    """ run time: 5.0076s """
    df = df.astype(str)
    return df[0] + df[1] + df[2] + df[3] + df[4] + \
           df[5] + df[6] + df[7] + df[8] + df[9]


def concat_df_str4(df):
    """ run time: 7.8624s """
    return df.astype(str).apply(lambda x: ''.join(x), axis=1)


def main():
    df = pd.DataFrame(np.zeros(1000000).reshape(100000, 10))
    df = df.astype(int)

    time1 = time()
    df_en = concat_df_str4(df)
    print('run time: %.4fs' % (time() - time1))
    print(df_en.head(10))


if __name__ == '__main__':
    main()

final, ketika sum(concat_df_str2) digunakan, hasilnya tidak hanya concat, itu akan ditransformasikan ke integer.


Solusi 1 Rapi, ini juga memungkinkan kita untuk menentukan kolom: misalnya df.values[:, 0:3]atau df.values[:, [0,2]].
Snow bunting

9

generalisasi ke beberapa kolom, mengapa tidak:

columns = ['whatever', 'columns', 'you', 'choose']
df['period'] = df[columns].astype(str).sum(axis=1)

Terlihat keren tapi bagaimana jika saya ingin menambahkan pembatas di antara string, seperti '-'?
Odisseo


6

Menggunakan zipbisa lebih cepat:

df["period"] = [''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]

Grafik:

masukkan deskripsi gambar di sini

import pandas as pd
import numpy as np
import timeit
import matplotlib.pyplot as plt
from collections import defaultdict

df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})

myfuncs = {
"df['Year'].astype(str) + df['quarter']":
    lambda: df['Year'].astype(str) + df['quarter'],
"df['Year'].map(str) + df['quarter']":
    lambda: df['Year'].map(str) + df['quarter'],
"df.Year.str.cat(df.quarter)":
    lambda: df.Year.str.cat(df.quarter),
"df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)":
    lambda: df.loc[:, ['Year','quarter']].astype(str).sum(axis=1),
"df[['Year','quarter']].astype(str).sum(axis=1)":
    lambda: df[['Year','quarter']].astype(str).sum(axis=1),
    "df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)":
    lambda: df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1),
    "[''.join(i) for i in zip(dataframe['Year'].map(str),dataframe['quarter'])]":
    lambda: [''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]
}

d = defaultdict(dict)
step = 10
cont = True
while cont:
    lendf = len(df); print(lendf)
    for k,v in myfuncs.items():
        iters = 1
        t = 0
        while t < 0.2:
            ts = timeit.repeat(v, number=iters, repeat=3)
            t = min(ts)
            iters *= 10
        d[k][lendf] = t/iters
        if t > 2: cont = False
    df = pd.concat([df]*step)

pd.DataFrame(d).plot().legend(loc='upper center', bbox_to_anchor=(0.5, -0.15))
plt.yscale('log'); plt.xscale('log'); plt.ylabel('seconds'); plt.xlabel('df rows')
plt.show()

6

Solusi paling sederhana:

Solusi Umum

df['combined_col'] = df[['col1', 'col2']].astype(str).apply('-'.join, axis=1)

Solusi khusus pertanyaan

df['quarter_year'] = df[['quarter', 'year']].astype(str).apply(''.join, axis=1)

Tentukan pembatas yang disukai di dalam tanda kutip sebelum .join


Apakah ini tidak identik dengan jawaban yang lebih lama dan lebih populer ?
AMC

5

Solusi ini menggunakan langkah menengah mengompresi dua kolom DataFrame ke satu kolom yang berisi daftar nilai. Ini berfungsi tidak hanya untuk string tetapi untuk semua jenis kolom-dtypes

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})
df['list']=df[['Year','quarter']].values.tolist()
df['period']=df['list'].apply(''.join)
print(df)

Hasil:

   Year quarter        list  period
0  2014      q1  [2014, q1]  2014q1
1  2015      q2  [2015, q2]  2015q2

Sepertinya dtypes lain tidak akan berfungsi. Saya mendapat TypeError: item urutan 1: diharapkan str contoh, float found
Prometheus

terapkan terlebih dahulu gips ke string. Operasi gabungan hanya berfungsi untuk string
Markus Dutschke

Solusi ini tidak akan berhasil menggabungkan dua kolom dengan tipe yang berbeda, lihat jawaban saya untuk solusi yang tepat untuk kasus tersebut.
Good Will

2

Seperti banyak yang telah disebutkan sebelumnya, Anda harus mengubah setiap kolom menjadi string dan kemudian menggunakan operator plus untuk menggabungkan dua kolom string. Anda bisa mendapatkan peningkatan kinerja besar dengan menggunakan NumPy.

%timeit df['Year'].values.astype(str) + df.quarter
71.1 ms ± 3.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df['Year'].astype(str) + df['quarter']
565 ms ± 22.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Saya ingin menggunakan versi numpyified tapi aku mendapatkan error: Masukan : df2['filename'] = df2['job_number'].values.astype(str) + '.' + df2['task_number'].values.astype(str)-> Keluaran : TypeError: ufunc 'add' did not contain a loop with signature matching types dtype('<U21') dtype('<U21') dtype('<U21'). Baik job_number dan task_number adalah int.
Karl Baker

Itu karena Anda menggabungkan dua array numpy. Ini berfungsi jika Anda menggabungkan array numpy dengan panda Series. asdf['Year'].values.astype(str) + df.quarter
AbdulRehmanLiaqat

2

Saya pikir cara terbaik untuk menggabungkan kolom dalam panda adalah dengan mengubah kedua kolom menjadi integer dan kemudian ke str.

df[['Year', 'quarter']] = df[['Year', 'quarter']].astype(int).astype(str)
df['Period']= df['Year'] + 'q' + df['quarter']

mengkonversi kedua kolom menjadi integer Mengapa mengkonversi ke int terlebih dahulu? Setelah Anda menghilangkan keanehan itu, solusi ini identik dengan jawaban teratas saat ini.
AMC

2

Berikut ini adalah ringkasan saya dari solusi di atas untuk menggabungkan / menggabungkan dua kolom dengan nilai int dan str ke dalam kolom baru, menggunakan pemisah antara nilai kolom. Tiga solusi berfungsi untuk tujuan ini.

# be cautious about the separator, some symbols may cause "SyntaxError: EOL while scanning string literal".
# e.g. ";;" as separator would raise the SyntaxError

separator = "&&" 

# pd.Series.str.cat() method does not work to concatenate / combine two columns with int value and str value. This would raise "AttributeError: Can only use .cat accessor with a 'category' dtype"

df["period"] = df["Year"].map(str) + separator + df["quarter"]
df["period"] = df[['Year','quarter']].apply(lambda x : '{} && {}'.format(x[0],x[1]), axis=1)
df["period"] = df.apply(lambda x: f'{x["Year"]} && {x["quarter"]}', axis=1)

Terima kasih! Solusi f-string Anda adalah apa yang saya harapkan !!!
leerssej

1

Gunakan .combine_first.

df['Period'] = df['Year'].combine_first(df['Quarter'])

Ini tidak benar. .combine_firstakan menghasilkan nilai dari 'Year'disimpan di 'Period', atau, jika Null, nilai dari 'Quarter'. Itu tidak akan menyatukan dua string dan menyimpannya 'Period'.
Steve G

Ini salah.
AMC

0
def madd(x):
    """Performs element-wise string concatenation with multiple input arrays.

    Args:
        x: iterable of np.array.

    Returns: np.array.
    """
    for i, arr in enumerate(x):
        if type(arr.item(0)) is not str:
            x[i] = x[i].astype(str)
    return reduce(np.core.defchararray.add, x)

Sebagai contoh:

data = list(zip([2000]*4, ['q1', 'q2', 'q3', 'q4']))
df = pd.DataFrame(data=data, columns=['Year', 'quarter'])
df['period'] = madd([df[col].values for col in ['Year', 'quarter']])

df

    Year    quarter period
0   2000    q1  2000q1
1   2000    q2  2000q2
2   2000    q3  2000q3
3   2000    q4  2000q4

0

Seseorang dapat menggunakan metode assign dari DataFrame :

df= (pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']}).
  assign(period=lambda x: x.Year+x.quarter ))

-1
dataframe["period"] = dataframe["Year"].astype(str).add(dataframe["quarter"])

atau jika nilainya seperti [2000] [4] dan ingin membuat [2000q4]

dataframe["period"] = dataframe["Year"].astype(str).add('q').add(dataframe["quarter"]).astype(str)

menggantikan .astype(str)dengan .map(str)karya juga.


Ini pada dasarnya identik dengan jawaban teratas.
AMC
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.