iloc
팬더에서 사용하는 다른 인덱싱 방법과 혼동됩니다 .
1-d 데이터 프레임을 2-d 데이터 프레임으로 변환하려고한다고 가정 해 봅시다. 먼저 다음 1-d 데이터 프레임이 있습니다.
a_array = [1,2,3,4,5,6,7,8]
a_df = pd.DataFrame(a_array).T
그리고 크기를 2 차원 데이터 프레임으로 변환하려고합니다 2x4
. 다음과 같이 2 차원 데이터 프레임을 사전 설정하여 시작합니다.
b_df = pd.DataFrame(columns=range(4),index=range(2))
그런 다음 for-loop를 사용하여 다음 코드 로 a_df
(1-d)를 b_df
(2-d)로 변환하는 데 도움이 됩니다.
for i in range(2):
b_df.iloc[i,:] = a_df.iloc[0,i*4:(i+1)*4]
그것은 단지 나에게 다음과 같은 결과를 제공합니다
0 1 2 3
0 1 2 3 4
1 NaN NaN NaN NaN
하지만 변경하는 경우 b_df.iloc[i,:]
에 b_df.iloc[i][:]
. 결과는 다음과 같이 정확합니다.
0 1 2 3
0 1 2 3 4
1 5 6 7 8
누구든지 .iloc[i,:]
와 의 차이점 과 위의 예에서 .iloc[i][:]
왜 .iloc[i][:]
효과 가 있었는지 설명 할 수 있습니까 ?.iloc[i,:]
답변
사이에는 매우 큰 차이가 있습니다 series.iloc[:]
series[:]
다시 할당 할 때 와와 ( 있습니다. (i)loc
할당하려는 항목이 양수인의 색인과 일치하는지 항상 확인합니다. 한편, [:]
구문은 인덱스 정렬을 무시하고 기본 NumPy 배열에 할당합니다.
s = pd.Series(index=[0, 1, 2, 3], dtype='float')
s
0 NaN
1 NaN
2 NaN
3 NaN
dtype: float64
# Let's get a reference to the underlying array with `copy=False`
arr = s.to_numpy(copy=False)
arr
# array([nan, nan, nan, nan])
# Reassign using slicing syntax
s[:] = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
s
0 1
1 2
2 3
3 4
dtype: int64
arr
# array([1., 2., 3., 4.]) # underlying array has changed
# Now, reassign again with `iloc`
s.iloc[:] = pd.Series([5, 6, 7, 8], index=[3, 4, 5, 6])
s
0 NaN
1 NaN
2 NaN
3 5.0
dtype: float64
arr
# array([1., 2., 3., 4.]) # `iloc` created a new array for the series
# during reassignment leaving this unchanged
s.to_numpy(copy=False) # the new underlying array, for reference
# array([nan, nan, nan, 5.])
차이점을 이해 했으므로 코드에서 어떤 일이 발생하는지 살펴 보겠습니다. 루프의 RHS를 인쇄하여 할당 대상을 확인하십시오.
for i in range(2):
print(a_df.iloc[0, i*4:(i+1)*4])
# output - first row
0 1
1 2
2 3
3 4
Name: 0, dtype: int64
# second row. Notice the index is different
4 5
5 6
6 7
7 8
Name: 0, dtype: int64
b_df.iloc[i, :]
두 번째 반복에서 할당 할 때 인덱스가 다르므로 할당 된 것이 없으며 NaN 만 표시됩니다. 그러나 변경 b_df.iloc[i, :]
하려면 b_df.iloc[i][:]
색인 정렬이 바이 패스 있도록, 기본 NumPy와 배열에 할당 의미합니다. 이 작업은 다음과 같이 더 잘 표현됩니다.
for i in range(2):
b_df.iloc[i, :] = a_df.iloc[0, i*4:(i+1)*4].to_numpy()
b_df
0 1 2 3
0 1 2 3 4
1 5 6 7 8
또한 이것이 일종의 체인 할당이라는 것을 언급 할 가치 가 있으며, 이는 좋은 일이 아니며 코드를 읽고 이해하기 어렵게 만듭니다.
답변
차이점은 첫 번째 경우 Python 인터프리터가 코드를 다음과 같이 실행한다는 것입니다.
b_df.iloc[i,:] = a_df.iloc[0,i*4:(i+1)*4]
#as
b_df.iloc.__setitem__((i, slice(None)), value)
여기서 값은 방정식의 오른쪽입니다. 두 번째 경우에는 파이썬 인터프리터가 코드를 다음과 같이 실행했습니다.
b_df.iloc[i][:] = a_df.iloc[0,i*4:(i+1)*4]
#as
b_df.iloc.__getitem__(i).__setitem__(slice(None), value)
다시 값은 방정식의 오른쪽입니다.
이 두 경우 각각 키 (i, slice (None))와 slice (None)의 차이로 인해 setitem 내에서 다른 메소드가 호출 되므로 동작이 다릅니다.
답변
사람이 나에게 무엇의 차이를 설명 할 수
.iloc[i,:]
및
.iloc[i][:]
입니다
차이점 .iloc[i,:]
및.iloc[i][:]
의 ( ) 열을 모두 선택하여 .iloc[i,:]
의 특정 위치에 직접 액세스 하는 경우DataFrame
:
i
번째 행 . 내가 아는 한, 2 차원을 지정하지 않은 상태 (.iloc[i]
) .
.iloc[i][:]
2 개의 체인 작업을 수행하는 경우 . 따라서의 결과는의 .iloc[i]
영향을받습니다 [:]
. 이 값을 사용하여 값을 설정하는 것은 Pandas 자체 에서 경고와 함께 권장하지 않으므로 사용해서는 안됩니다.
설정 조작에 대해 사본 또는 참조가 리턴되는지 여부는 컨텍스트에 따라 달라질 수 있습니다. 이를 체인 할당이라고도하며 피해야합니다
… 그리고 왜
.iloc[i][:]
위의 예에서 효과가 있었습니까?.iloc[i,:]
OP 주석에서 @Scott이 언급했듯이 데이터 정렬은 본질적 이므로 =
왼쪽에없는 경우 오른쪽의 인덱스는 포함되지 않습니다. 이것이 이유입니다NaN
두 번째 행에 값 입니다.
따라서 일을 명확하게하기 위해 다음과 같이 할 수 있습니다.
for i in range(2):
# Get the slice
a_slice = a_df.iloc[0, i*4:(i+1)*4]
# Reset the indices
a_slice.reset_index(drop=True, inplace=True)
# Set the slice into b_df
b_df.iloc[i,:] = a_slice
또는 다음 list
을 사용 하는 대신 로 변환 할 수 있습니다 reset_index
.
for i in range(2):
# Get the slice
a_slice = a_df.iloc[0, i*4:(i+1)*4]
# Convert the slice into a list and set it into b_df
b_df.iloc[i,:] = list(a_slice)